sr_friction_compensation.cpp
Go to the documentation of this file.
1 
27 
28 #include <utility>
29 #include <vector>
30 #include <string>
31 #include <sstream>
32 #include <math.h>
35 
36 using std::string;
37 using std::vector;
38 using std::pair;
39 
41 {
43 
45  joint_name_(joint_name)
46  {
47  pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > both_maps = read_friction_map();
50  }
51 
53  {
54  }
55 
56  double SrFrictionCompensator::friction_compensation(double position, double velocity, int force_demand, int deadband)
57  {
58  double compensation = 0.0;
59 
60  if (force_demand > 0.0)
61  {
62  compensation = friction_interpoler_forward->compute(position);
63  }
64  else
65  {
66  compensation = friction_interpoler_backward->compute(position);
67  }
68 
69  // A value by which we'll multiply the compensation computed by the
70  // friction map.
71  double mult = 1.0;
72  // we're out of the "finger is stopped" zone ->
73  // progressively decrease the amount of compensation
74  if (fabs(velocity) > velocity_for_static_friction)
75  {
76  if (velocity < 0.0)
77  {
78  mult = exp(-fabs(velocity + velocity_for_static_friction) * 20);
79  }
80  else
81  {
82  mult = exp(-fabs(velocity - velocity_for_static_friction) * 20);
83  }
84  }
85 
86  // decrease the compensation around the force sign change
87  // to have less discontinuity. Use the deadband for this.
88  if (abs(force_demand) < deadband)
89  {
90  // we want the multiplier to be 1 if force_demand = deadband
91  // and 0 if force_demand = 0
92  mult *= sr_math_utils::linear_interpolate_(static_cast<double> (abs(force_demand)),
93  0.0, 0.0,
94  static_cast<double> (deadband), 1.0);
95  }
96 
97  // amend the compensation value
98  compensation *= mult;
99 
100  return compensation;
101  }
102 
103  pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > SrFrictionCompensator::read_friction_map()
104  {
105  vector<joint_calibration::Point> friction_map_forward, friction_map_backward;
106  string param_name = "/sr_friction_map";
107 
108  bool joint_not_found_forward = true;
109  bool joint_not_found_backward = true;
110 
111  XmlRpc::XmlRpcValue calib;
112  if (node_.hasParam(param_name))
113  {
114  node_.getParam(param_name, calib);
115 
116  ROS_DEBUG_STREAM(" Reading friction for: " << joint_name_);
117  ROS_DEBUG_STREAM(" value: " << calib);
118 
120  // iterate on all the joints
121  for (int32_t index_cal = 0; index_cal < calib.size(); ++index_cal)
122  {
123  // check the calibration is well formatted:
124  // first joint name, then calibration table
125  ROS_ASSERT(calib[index_cal][0].getType() == XmlRpc::XmlRpcValue::TypeString);
126  ROS_ASSERT(calib[index_cal][1].getType() == XmlRpc::XmlRpcValue::TypeInt);
127  ROS_ASSERT(calib[index_cal][2].getType() == XmlRpc::XmlRpcValue::TypeArray);
128 
129  string joint_name_tmp = static_cast<string> (calib[index_cal][0]);
130 
131  ROS_DEBUG_STREAM(" Checking joint name: " << joint_name_tmp << " / " << joint_name_);
132  if (joint_name_tmp.compare(joint_name_) != 0)
133  {
134  continue;
135  }
136 
137  // reading the forward map:
138  if (static_cast<int> (calib[index_cal][1]) == 1)
139  {
140  joint_not_found_forward = false;
141 
142  friction_map_forward = read_one_way_map(calib[index_cal][2]);
143  }
144  else
145  {
146  joint_not_found_backward = false;
147 
148  friction_map_backward = read_one_way_map(calib[index_cal][2]);
149  }
150  }
151  }
152 
153  if (joint_not_found_forward)
154  {
155  ROS_INFO_STREAM(" No forward friction compensation map for: " << joint_name_);
156 
157  friction_map_forward = generate_flat_map();
158  }
159 
160  if (joint_not_found_backward)
161  {
162  ROS_INFO_STREAM(" No backward friction compensation map for: " << joint_name_);
163 
164  friction_map_backward = generate_flat_map();
165  }
166 
167  /*
168  ROS_INFO_STREAM(" Friction map forward: [" << joint_name_ << "]");
169  for( unsigned int i=0; i<friction_map_forward.size(); ++i )
170  ROS_INFO_STREAM(" -> position=" << friction_map_forward[i].raw_value << " compensation: " << friction_map_forward[i].calibrated_value);
171  ROS_INFO_STREAM(" Friction map backward: [" << joint_name_ << "]");
172  for( unsigned int i=0; i<friction_map_backward.size(); ++i )
173  ROS_INFO_STREAM(" -> position=" << friction_map_backward[i].raw_value << " compensation: " << friction_map_backward[i].calibrated_value);
174  */
175 
176  pair<vector<joint_calibration::Point>, vector<joint_calibration::Point> > both_maps;
177  both_maps.first = friction_map_forward;
178  both_maps.second = friction_map_backward;
179 
180  return both_maps;
181  } // end read_friction_map
182 
183  vector<joint_calibration::Point> SrFrictionCompensator::read_one_way_map(XmlRpc::XmlRpcValue &raw_map)
184  {
185  vector<joint_calibration::Point> friction_map;
186 
187  // now iterates on the calibration table for the current joint
188  for (int32_t index_table = 0; index_table < raw_map.size(); ++index_table)
189  {
190  ROS_ASSERT(raw_map[index_table].getType() == XmlRpc::XmlRpcValue::TypeArray);
191  // only 2 values per calibration point: raw and calibrated (doubles)
192  ROS_ASSERT(raw_map[index_table].size() == 2);
193  ROS_ASSERT(raw_map[index_table][0].getType() == XmlRpc::XmlRpcValue::TypeDouble);
194  ROS_ASSERT(raw_map[index_table][1].getType() == XmlRpc::XmlRpcValue::TypeDouble);
195 
196 
197  joint_calibration::Point point_tmp;
198  point_tmp.raw_value = sr_math_utils::to_rad(static_cast<double> (raw_map[index_table][0]));
199  point_tmp.calibrated_value = static_cast<double> (raw_map[index_table][1]);
200  friction_map.push_back(point_tmp);
201  }
202 
203  return friction_map;
204  }
205 
206  vector<joint_calibration::Point> SrFrictionCompensator::generate_flat_map()
207  {
208  vector<joint_calibration::Point> friction_map;
209 
210  joint_calibration::Point point_tmp;
211  point_tmp.raw_value = 0.0;
212  point_tmp.calibrated_value = 0.0;
213  friction_map.push_back(point_tmp);
214  point_tmp.raw_value = 1.0;
215  friction_map.push_back(point_tmp);
216 
217  return friction_map;
218  }
219 } // namespace sr_friction_compensation
220 
221 
222 
223 /* For the emacs weenies in the crowd.
224  Local Variables:
225  c-basic-offset: 2
226  End:
227  */
228 
229 
std::vector< joint_calibration::Point > generate_flat_map()
std::pair< std::vector< joint_calibration::Point >, std::vector< joint_calibration::Point > > read_friction_map()
int size() const
double friction_compensation(double position, double velocity, int force_demand, int deadband)
Type const & getType() const
static double to_rad(double degrees)
Compensate the tendon friction by adding a given value depending on the sign of the force demand...
boost::scoped_ptr< shadow_robot::JointCalibration > friction_interpoler_backward
An interpolator for the backward friction map: used to compute the offset from the map...
static double linear_interpolate_(double x, double x0, double y0, double x1, double y1)
ros::NodeHandle node_
node handle for reading the map from the parameters server.
#define ROS_DEBUG_STREAM(args)
#define ROS_INFO_STREAM(args)
bool getParam(const std::string &key, std::string &s) const
std::vector< joint_calibration::Point > read_one_way_map(XmlRpc::XmlRpcValue &raw_map)
boost::scoped_ptr< shadow_robot::JointCalibration > friction_interpoler_forward
An interpolator for the forward friction map: used to compute the offset from the map...
bool hasParam(const std::string &key) const
#define ROS_ASSERT(cond)


sr_mechanism_controllers
Author(s): Ugo Cupcic
autogenerated on Tue Oct 13 2020 03:55:58