iSpike
2.1
Spike conversion library for robotics
|
00001 #include <iSpike/Writer/YarpAngleWriter.hpp> 00002 #include <iSpike/YarpPortDetails.hpp> 00003 #include <iSpike/YarpConnection.hpp> 00004 #include <iSpike/Log/Log.hpp> 00005 #include <iSpike/ISpikeException.hpp> 00006 using namespace ispike; 00007 00008 #include <sstream> 00009 #include <iostream> 00010 using namespace std; 00011 00012 //Names of properties used 00013 #define PORT_NAME_PROP "Port Name" 00014 #define SLEEP_DURATION_PROP "Sleep Duration ms" 00015 00016 00018 YarpAngleWriter::YarpAngleWriter(string nameserverIP, unsigned nameserverPort){ 00019 // Connect to YARP and get list of ports 00020 yarpConnection = NULL; 00021 yarpConnection = new YarpConnection(nameserverIP, nameserverPort); 00022 map<string, YarpPortDetails>& portMap = yarpConnection->getPortMap(); 00023 00024 //Store port names as properties of this reader 00025 vector<string> yarpPortNames; 00026 for (map<string, YarpPortDetails>::iterator iter = portMap.begin(); iter != portMap.end(); iter++){ 00027 yarpPortNames.push_back(iter->first); 00028 } 00029 if(yarpPortNames.empty()) 00030 addProperty(Property("undefined", yarpPortNames, PORT_NAME_PROP, "The Yarp Port name", true)); 00031 else 00032 addProperty(Property(yarpPortNames[0], yarpPortNames, PORT_NAME_PROP, "The Yarp Port name", true)); 00033 00034 //Other properties 00035 addProperty(Property(Property::Integer, 50, SLEEP_DURATION_PROP, "Amount to sleep in milliseconds in between sending command.", false)); 00036 00037 //Create the description 00038 writerDescription = Description("Yarp Angle Writer", "This is a Yarp angle writer", "Angle Writer"); 00039 00040 //Initialize variables 00041 angleChanged = false; 00042 degreeOfFreedom = -1; 00043 } 00044 00045 00047 YarpAngleWriter::~YarpAngleWriter(){ 00048 if(isRunning()){ 00049 requestStop(); 00050 getThreadPointer()->join(); 00051 } 00052 if(yarpConnection != NULL) 00053 delete yarpConnection; 00054 } 00055 00056 00057 /*--------------------------------------------------------------------*/ 00058 /*--------- PUBLIC METHODS -------*/ 00059 /*--------------------------------------------------------------------*/ 00060 00061 // Inherited from Writer 00062 void YarpAngleWriter::initialize(map<string,Property>& properties){ 00063 updateProperties(properties); 00064 setInitialized(true); 00065 } 00066 00067 00068 // Inherited from AngleWriter 00069 void YarpAngleWriter::setAngle(double newAngle){ 00070 if(this->angle != newAngle){ 00071 this->angle = newAngle; 00072 angleChanged = true; 00073 } 00074 } 00075 00076 00077 // Inherited from AngleWriter 00078 void YarpAngleWriter::setDegreeOfFreedom(int dof){ 00079 if(this->degreeOfFreedom != dof){ 00080 this->degreeOfFreedom = dof; 00081 angleChanged = true; 00082 } 00083 } 00084 00085 00086 //Inherited from PropertyHolder 00087 void YarpAngleWriter::setProperties(map<string, Property> &properties){ 00088 updateProperties(properties); 00089 } 00090 00091 00092 // Inherited from iSpikeThread 00093 void YarpAngleWriter::start(){ 00094 if(!isInitialized()) 00095 throw ISpikeException("Cannot start YarpAngleWriter thread - it has not been initialized."); 00096 if(isRunning()) 00097 throw ISpikeException("Cannot start YarpAngleWriter thread - it is already running."); 00098 00099 this->setThreadPointer(boost::shared_ptr<boost::thread>(new boost::thread(boost::bind(&YarpAngleWriter::workerFunction, this)))); 00100 } 00101 00102 00103 /*--------------------------------------------------------------------*/ 00104 /*--------- PRIVATE METHODS -------*/ 00105 /*--------------------------------------------------------------------*/ 00106 00108 void YarpAngleWriter::updateProperties(map<string, Property>& properties){ 00109 if(!isInitialized()) 00110 portName = updateComboProperty(properties[PORT_NAME_PROP]); 00111 00112 sleepDuration_ms = updateIntegerProperty(properties[SLEEP_DURATION_PROP]); 00113 } 00114 00115 00116 //Inherited from iSpikeThread 00117 void YarpAngleWriter::workerFunction(){ 00118 setRunning(true); 00119 clearError(); 00120 00121 try{ 00122 //Connect to YARP 00123 map<string, YarpPortDetails>& portMap = yarpConnection->getPortMap(); 00124 map<string, YarpPortDetails>::iterator iter = portMap.find(portName); 00125 if(iter == portMap.end()) 00126 throw ISpikeException("YarpAngleWriter: Cannot find port name in port map"); 00127 string ip = iter->second.getIp(); 00128 unsigned port = iter->second.getPort(); 00129 00130 yarpConnection->connect_to_port(ip, port); 00131 yarpConnection->write_text("CONNECT foo\n"); 00132 00133 //Main run loop 00134 unsigned loopCtr = 0; 00135 while(!isStopRequested()){ 00136 if(loopCtr % 20 == 0) 00137 LOG(LOG_DEBUG)<<"YarpAngleWriter: Checking for new angle."; 00138 if(angleChanged){ 00139 //Send new angle 00140 yarpConnection->write_text("d\n"); 00141 ostringstream commandStream; 00142 commandStream << "set pos " << degreeOfFreedom << " " << angle << "\n"; 00143 string command = commandStream.str(); 00144 LOG(LOG_DEBUG) << "YarpAngleWriter: Sending command " << command; 00145 this->yarpConnection->write_text(command); 00146 LOG(LOG_DEBUG) << "YarpAngleWriter: Received reply " << this->yarpConnection->read_until("\n"); 00147 00148 //Record that we have sent angle 00149 angleChanged = false; 00150 } 00151 00152 //Sleep for the specified amount 00153 if(sleepDuration_ms > 0) 00154 boost::this_thread::sleep(boost::posix_time::milliseconds(sleepDuration_ms)); 00155 ++loopCtr; 00156 } 00157 } 00158 catch(ISpikeException& ex){ 00159 setError(ex.msg()); 00160 } 00161 catch(exception& ex){ 00162 LOG(LOG_CRITICAL)<<"YarpAngleWriter exception: "<<ex.what(); 00163 setError("An exception occurred in the YarpAngleWriter."); 00164 } 00165 catch(...){ 00166 setError("An unknown exception occurred in the YarpAngleWriter"); 00167 } 00168 00169 setRunning(false); 00170 }