00001 // 00002 // Created by tom on 10/05/16. 00003 // 00004 00005 #include <robotican_hardware_interface/Servo.h> 00006 00007 namespace robotican_hardware { 00008 00009 Servo::Servo(byte id, TransportLayer *transportLayer, byte pin, float a, float b, float max, float min, 00010 float initPos, std::string jointName) : Device(id , transportLayer), 00011 _mutex(), _nodeHandle((std::string("~/") + jointName)), _server(_mutex, _nodeHandle) { 00012 _callbackType = boost::bind(&Servo::dynamicCallback, this, _1, _2); 00013 _server.setCallback(_callbackType); 00014 _pin = pin; 00015 _a = a; 00016 _b = b; 00017 _max = max; 00018 _min = min; 00019 _lastCmd = 0.0; 00020 _isChangeParam = false; 00021 00022 00023 robotican_hardware_interface::RiCBoardServoConfig config; 00024 config.A = _a; 00025 config.B = _b; 00026 config.max = _max; 00027 config.min = _min; 00028 00029 _server.updateConfig(config); 00030 00031 00032 } 00033 00034 00035 00036 00037 void Servo::update(const DeviceMessage *deviceMessage) { 00038 if(isReady()) { 00039 ServoFeedback *feedback = (ServoFeedback *) deviceMessage; 00040 _jointInfo.position = feedback->pos; 00041 } 00042 } 00043 00044 void Servo::write() { 00045 if(isReady()) { 00046 if(checkIfLastCmdChange()) { 00047 ServoSetPoint point; 00048 point.length = sizeof(point); 00049 point.checkSum = 0; 00050 point.id = getId(); 00051 point.pos = (float) _jointInfo.cmd; 00052 00053 uint8_t *rawData = (uint8_t *) &point; 00054 point.checkSum = _transportLayer->calcChecksum(rawData, point.length); 00055 _transportLayer->write(rawData, point.length); 00056 _lastCmd = (float) _jointInfo.cmd; 00057 } 00058 if(_isChangeParam) { 00059 _isChangeParam = false; 00060 SetServoParam param; 00061 param.length = sizeof(param); 00062 param.checkSum = 0; 00063 param.id = getId(); 00064 param.a = _a; 00065 param.b = _b; 00066 param.max = _max; 00067 param.min = _min; 00068 00069 uint8_t *rawData = (uint8_t*) ¶m; 00070 param.checkSum = _transportLayer->calcChecksum(rawData, param.length); 00071 _transportLayer->write(rawData, param.length); 00072 } 00073 } 00074 } 00075 00076 JointInfo_t* Servo::getJointInfo() { 00077 return &_jointInfo; 00078 } 00079 00080 void Servo::buildDevice() { 00081 BuildServo buildServo; 00082 buildServo.length = sizeof(buildServo); 00083 buildServo.checkSum = 0; 00084 buildServo.id = getId(); 00085 buildServo.pin = _pin; 00086 buildServo.a = _a; 00087 buildServo.b = _b; 00088 buildServo.max = _max; 00089 buildServo.min = _min; 00090 00091 uint8_t* rawData = (uint8_t*)&buildServo; 00092 buildServo.checkSum = _transportLayer->calcChecksum(rawData, buildServo.length); 00093 _transportLayer->write(rawData, buildServo.length); 00094 } 00095 00096 00097 void Servo::deviceAck(const DeviceAck *ack) { 00098 Device::deviceAck(ack); 00099 if(isReady()) { 00100 ros_utils::rosInfo("Servo is ready"); 00101 } 00102 else { 00103 ros_utils::rosError("Can't build Servo for some reason"); 00104 ros::shutdown(); 00105 } 00106 } 00107 00108 bool Servo::checkIfLastCmdChange() { 00109 float delta = fabsf((float) (_jointInfo.cmd - _lastCmd)); 00110 return delta >= SERVO_EPSILON; 00111 } 00112 00113 void Servo::setParam(float a, float b, float max, float min) { 00114 _isChangeParam = true; 00115 _a = a; 00116 _b = b; 00117 _max = max; 00118 _min = min; 00119 00120 } 00121 00122 void Servo::dynamicCallback(robotican_hardware_interface::RiCBoardServoConfig &config, uint32_t level) { 00123 setParam((float) config.A, (float) config.B, (float) config.max, (float) config.min); 00124 00125 } 00126 }