Go to the documentation of this file.00001
00026 #include "sr_mechanism_controllers/sr_friction_compensation.hpp"
00027
00028 #include <sstream>
00029 #include <math.h>
00030 #include "sr_utilities/sr_math_utils.hpp"
00031 #include "sr_utilities/sr_deadband.hpp"
00032
00033 using namespace std;
00034
00035 namespace sr_friction_compensation
00036 {
00037 const double SrFrictionCompensator::velocity_for_static_friction = 0.01;
00038
00039 SrFrictionCompensator::SrFrictionCompensator(const string &joint_name) :
00040 joint_name_(joint_name)
00041 {
00042 pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > both_maps = read_friction_map();
00043 friction_interpoler_forward.reset(new shadow_robot::JointCalibration(both_maps.first));
00044 friction_interpoler_backward.reset(new shadow_robot::JointCalibration(both_maps.second));
00045 }
00046
00047 SrFrictionCompensator::~SrFrictionCompensator()
00048 {
00049 }
00050
00051 double SrFrictionCompensator::friction_compensation(double position, double velocity, int force_demand, int deadband)
00052 {
00053 double compensation = 0.0;
00054
00055 if (force_demand > 0.0)
00056 compensation = friction_interpoler_forward->compute(position);
00057 else
00058 compensation = friction_interpoler_backward->compute(position);
00059
00060
00061
00062 double mult = 1.0;
00063
00064
00065 if (fabs(velocity) > velocity_for_static_friction)
00066 {
00067 if (velocity < 0.0)
00068 mult = exp(-fabs(velocity + velocity_for_static_friction)*20);
00069 else
00070 mult = exp(-fabs(velocity - velocity_for_static_friction)*20);
00071 }
00072
00073
00074
00075 if (abs(force_demand) < deadband)
00076 {
00077
00078
00079 mult *= sr_math_utils::linear_interpolate_(static_cast<double> (abs(force_demand)),
00080 0.0, 0.0,
00081 static_cast<double> (deadband), 1.0);
00082 }
00083
00084
00085 compensation *= mult;
00086
00087 return compensation;
00088 }
00089
00090 pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > SrFrictionCompensator::read_friction_map()
00091 {
00092 vector<joint_calibration::Point> friction_map_forward, friction_map_backward;
00093 string param_name = "/sr_friction_map";
00094
00095 bool joint_not_found_forward = true;
00096 bool joint_not_found_backward = true;
00097
00098 XmlRpc::XmlRpcValue calib;
00099 if (node_.hasParam(param_name))
00100 {
00101 node_.getParam(param_name, calib);
00102
00103 ROS_DEBUG_STREAM(" Reading friction for: " << joint_name_);
00104 ROS_DEBUG_STREAM(" value: " << calib);
00105
00106 ROS_ASSERT(calib.getType() == XmlRpc::XmlRpcValue::TypeArray);
00107
00108 for (int32_t index_cal = 0; index_cal < calib.size(); ++index_cal)
00109 {
00110
00111
00112 ROS_ASSERT(calib[index_cal][0].getType() == XmlRpc::XmlRpcValue::TypeString);
00113 ROS_ASSERT(calib[index_cal][1].getType() == XmlRpc::XmlRpcValue::TypeInt);
00114 ROS_ASSERT(calib[index_cal][2].getType() == XmlRpc::XmlRpcValue::TypeArray);
00115
00116 string joint_name_tmp = static_cast<string> (calib[index_cal][0]);
00117
00118 ROS_DEBUG_STREAM(" Checking joint name: " << joint_name_tmp << " / " << joint_name_);
00119 if (joint_name_tmp.compare(joint_name_) != 0)
00120 continue;
00121
00122
00123 if (static_cast<int> (calib[index_cal][1]) == 1)
00124 {
00125 joint_not_found_forward = false;
00126
00127 friction_map_forward = read_one_way_map(calib[index_cal][2]);
00128 }
00129 else
00130 {
00131 joint_not_found_backward = false;
00132
00133 friction_map_backward = read_one_way_map(calib[index_cal][2]);
00134 }
00135 }
00136 }
00137
00138 if (joint_not_found_forward)
00139 {
00140 ROS_INFO_STREAM(" No forward friction compensation map for: " << joint_name_);
00141
00142 friction_map_forward = generate_flat_map();
00143 }
00144
00145 if (joint_not_found_backward)
00146 {
00147 ROS_INFO_STREAM(" No backward friction compensation map for: " << joint_name_);
00148
00149 friction_map_backward = generate_flat_map();
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > both_maps;
00162 both_maps.first = friction_map_forward;
00163 both_maps.second = friction_map_backward;
00164
00165 return both_maps;
00166 }
00167
00168 vector<joint_calibration::Point> SrFrictionCompensator::read_one_way_map(XmlRpc::XmlRpcValue &raw_map)
00169 {
00170 vector<joint_calibration::Point> friction_map;
00171
00172
00173 for (int32_t index_table = 0; index_table < raw_map.size(); ++index_table)
00174 {
00175 ROS_ASSERT(raw_map[index_table].getType() == XmlRpc::XmlRpcValue::TypeArray);
00176
00177 ROS_ASSERT(raw_map[index_table].size() == 2);
00178 ROS_ASSERT(raw_map[index_table][0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00179 ROS_ASSERT(raw_map[index_table][1].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00180
00181
00182 joint_calibration::Point point_tmp;
00183 point_tmp.raw_value = sr_math_utils::to_rad(static_cast<double> (raw_map[index_table][0]));
00184 point_tmp.calibrated_value = static_cast<double> (raw_map[index_table][1]);
00185 friction_map.push_back(point_tmp);
00186 }
00187
00188 return friction_map;
00189 }
00190
00191 vector<joint_calibration::Point> SrFrictionCompensator::generate_flat_map()
00192 {
00193 vector<joint_calibration::Point> friction_map;
00194
00195 joint_calibration::Point point_tmp;
00196 point_tmp.raw_value = 0.0;
00197 point_tmp.calibrated_value = 0.0;
00198 friction_map.push_back(point_tmp);
00199 point_tmp.raw_value = 1.0;
00200 friction_map.push_back(point_tmp);
00201
00202 return friction_map;
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214