Libbarrett
1.2.4
|
00001 00026 /* 00027 * @file puck-inl.h 00028 * @date 10/05/2010 00029 * @author Dan Cody 00030 * 00031 */ 00032 00033 #include <boost/thread/locks.hpp> 00034 00035 #include <barrett/os.h> 00036 #include <barrett/thread/abstract/mutex.h> 00037 #include <barrett/products/puck_group.h> 00038 00039 00040 namespace barrett { 00041 00042 00043 inline int Puck::getProperty(enum Property prop, bool realtime) const { 00044 return getProperty(bus, id, getPropertyId(prop), realtime); 00045 } 00046 template<typename Parser> 00047 inline void Puck::getProperty(enum Property prop, typename Parser::result_type* result, bool realtime) const { 00048 getProperty<Parser> (bus, id, getPropertyId(prop), result, realtime); 00049 } 00050 00051 00052 inline int Puck::getProperty(const bus::CommunicationsBus& bus, int id, int propId, bool realtime) 00053 { 00054 int result; 00055 getProperty<StandardParser>(bus, id, propId, &result, realtime); 00056 return result; 00057 } 00058 // TODO(dc): throw exception if getProperty is called with a group ID? 00059 template<typename Parser> 00060 void Puck::getProperty(const bus::CommunicationsBus& bus, int id, int propId, typename Parser::result_type* result, bool realtime) 00061 { 00062 int ret = getPropertyHelper<Parser>(bus, id, propId, result, true, realtime, 0.0); 00063 if (ret != 0) { 00064 (logMessage("Puck::%s(): Failed to receive reply. " 00065 "Puck::receiveGetPropertyReply() returned error %d.") 00066 % __func__ % ret).template raise<std::runtime_error>(); 00067 } 00068 } 00069 00070 inline int Puck::tryGetProperty(const bus::CommunicationsBus& bus, int id, int propId, int* result, double timeout_s) 00071 { 00072 return tryGetProperty<StandardParser>(bus, id, propId, result, timeout_s); 00073 } 00074 template<typename Parser> 00075 int Puck::tryGetProperty(const bus::CommunicationsBus& bus, int id, int propId, typename Parser::result_type* result, double timeout_s) 00076 { 00077 int ret = getPropertyHelper<Parser>(bus, id, propId, result, false, false, timeout_s); 00078 if (ret != 0 && ret != 1) { // some error other than "would block" occurred 00079 (logMessage("Puck::%s(): Receive error. " 00080 "Puck::receiveGetPropertyReply() returned error %d.") 00081 % __func__ % ret).template raise<std::runtime_error>(); 00082 } 00083 return ret; 00084 } 00085 00086 template<typename Parser> 00087 int Puck::getPropertyHelper(const bus::CommunicationsBus& bus, int id, int propId, typename Parser::result_type* result, bool blocking, bool realtime, double timeout_s) 00088 { 00089 boost::unique_lock<thread::Mutex> ul(bus.getMutex(), boost::defer_lock); 00090 if (realtime) { 00091 ul.lock(); 00092 } 00093 00094 int ret = sendGetPropertyRequest(bus, id, propId); 00095 if (ret != 0) { 00096 (logMessage("Puck::%s(): Failed to send request. " 00097 "Puck::sendGetPropertyRequest() returned error %d.") 00098 % __func__ % ret).template raise<std::runtime_error>(); 00099 } 00100 00101 if (timeout_s != 0.0) { 00102 btsleepRT(timeout_s); 00103 } 00104 00105 return receiveGetPropertyReply<Parser>(bus, id, propId, result, blocking, realtime); 00106 } 00107 00108 inline void Puck::setProperty(const bus::CommunicationsBus& bus, int id, int propId, int value, bool blocking) 00109 { 00110 static const size_t MSG_LEN = 6; 00111 00112 unsigned char data[MSG_LEN]; 00113 data[0] = (propId & PROPERTY_MASK) | SET_MASK; 00114 data[1] = 0; 00115 data[2] = (value & 0x000000ff); 00116 data[3] = (value & 0x0000ff00) >> 8; 00117 data[4] = (value & 0x00ff0000) >> 16; 00118 data[5] = (value & 0xff000000) >> 24; 00119 00120 int ret = bus.send(nodeId2BusId(id), data, MSG_LEN); 00121 if (ret != 0) { 00122 (logMessage("Puck::%s(): Failed to send SET message. " 00123 "bus::CommunicationsBus::send() returned error %d.") 00124 % __func__ % ret).raise<std::runtime_error>(); 00125 } 00126 00127 if (blocking) { 00128 // Make sure the command has completed so we don't overflow the Puck's receive buffer. 00129 getProperty(bus, id, getPropertyId(STAT, PT_Unknown, 0)); 00130 } 00131 } 00132 00133 inline int Puck::sendGetPropertyRequest(const bus::CommunicationsBus& bus, int id, int propId) 00134 { 00135 static const size_t MSG_LEN = 1; 00136 00137 unsigned char data[MSG_LEN]; 00138 data[0] = propId & PROPERTY_MASK; 00139 00140 return bus.send(nodeId2BusId(id), data, MSG_LEN); 00141 } 00142 00143 inline int Puck::receiveGetPropertyReply(const bus::CommunicationsBus& bus, int id, int propId, int* result, bool blocking, bool realtime) 00144 { 00145 return receiveGetPropertyReply<StandardParser>(bus, id, propId, result, blocking, realtime); 00146 } 00147 template<typename Parser> 00148 int Puck::receiveGetPropertyReply(const bus::CommunicationsBus& bus, int id, int propId, typename Parser::result_type* result, bool blocking, bool realtime) 00149 { 00150 unsigned char data[bus::CommunicationsBus::MAX_MESSAGE_LEN]; 00151 size_t len; 00152 00153 int ret = bus.receive(Parser::busId(id, propId), data, len, blocking, realtime); 00154 if (ret != 0) { 00155 return ret; 00156 } 00157 00158 // Make return code negative to avoid colliding with bus.receive() return codes. 00159 return -Parser::parse(id, propId, result, data, len); 00160 } 00161 00162 inline int Puck::getPropertyId(enum Property prop, enum PuckType pt, int fwVers) 00163 throw(std::runtime_error) 00164 { 00165 int propId = getPropertyIdNoThrow(prop, pt, fwVers); 00166 if (propId == -1) { 00167 (logMessage("Puck::%s(): Invalid property. " 00168 "Pucks with type %s and firmware version %d do not respond to property %s.") 00169 % __func__ % getPuckTypeStr(pt) % fwVers % getPropertyStr(prop)).raise<std::runtime_error>(); 00170 } 00171 return propId; 00172 } 00173 00174 00175 inline int Puck::StandardParser::busId(int id, int propId) 00176 { 00177 return Puck::encodeBusId(id, PuckGroup::FGRP_OTHER); 00178 } 00179 00180 00181 }