33 #include <boost/foreach.hpp> 34 #include <boost/algorithm/string.hpp> 36 #include <sr_utilities/sr_math_utils.hpp> 43 using std::ostringstream;
44 using sr_actuator::SrMotorActuator;
51 using boost::static_pointer_cast;
55 template<
class StatusType,
class CommandType>
58 template<
class StatusType,
class CommandType>
59 const char *SrMotorHandLib<StatusType,
60 CommandType>::human_readable_motor_data_types[nb_motor_data] =
68 "can_num_transmitted",
76 template <
class StatusType,
class CommandType>
95 template<
class StatusType,
class CommandType>
98 string joint_prefix) :
99 SrMotorRobotLib<StatusType, CommandType>(hw, nh, nhtilde, device_id, joint_prefix)
102 this->motor_update_rate_configs_vector = this->read_update_rate_configs(
"motor_data_update_rate/", nb_motor_data,
103 human_readable_motor_data_types,
110 vector<JointToSensor> joint_to_sensor_vect = this->read_joint_to_sensor_mapping();
113 vector<string> joint_names_tmp;
114 vector<int> motor_ids = read_joint_to_motor_mapping();
121 joint_names_tmp.push_back(
string(joint_names[i]));
123 initialize(joint_names_tmp, motor_ids, joint_to_sensor_vect);
126 new MotorDataChecker(this->joints_vector, this->motor_updater_->initialization_configs_vector));
129 template<
class StatusType,
class CommandType>
131 vector<int> actuator_ids,
132 vector<JointToSensor> joint_to_sensors)
134 for (
unsigned int index = 0; index < joint_names.size(); ++index)
141 ostringstream full_param;
142 string act_name = boost::to_lower_copy(joint_names[index]);
143 full_param << act_name <<
"/pos_filter/tau";
144 this->nodehandle_.template param<float>(full_param.str(), tau, 0.05);
146 joint.
pos_filter = sr_math_utils::filters::LowPassFilter(tau);
152 if (actuator_ids[index] != -1)
157 motor_wrapper->motor_id = actuator_ids[index];
158 motor_wrapper->actuator =
static_cast<SrMotorActuator *
> (this->hw_->getActuator(
160 if (motor_wrapper->actuator == NULL)
164 " (check the robot_description contains it)");
170 ss <<
"change_force_PID_" << joint_names[index];
174 motor_wrapper->force_pid_service =
175 this->nh_tilde.template
advertiseService<sr_robot_msgs::ForceController::Request,
176 sr_robot_msgs::ForceController::Response>(ss.str().c_str(),
179 CommandType>::force_pid_callback,
181 motor_wrapper->motor_id));
184 ss <<
"reset_motor_" << joint_names[index];
186 motor_wrapper->reset_motor_service =
187 this->nh_tilde.template advertiseService<std_srvs::Empty::Request, std_srvs::Empty::Response>(
190 pair<int, string>(motor_wrapper->motor_id, joint.
joint_name)));
197 this->joints_vector.push_back(joint);
201 template<
class StatusType,
class CommandType>
203 std_srvs::Empty::Response &response,
204 pair<int, string> joint)
206 ROS_INFO_STREAM(
" resetting " << joint.second <<
" (" << joint.first <<
")");
208 this->reset_motors_queue.push(joint.first);
211 string joint_name = joint.second;
213 pid_timers[joint_name] = this->nh_tilde.createTimer(
ros::Duration(3.0),
214 boost::bind(&SrMotorHandLib::resend_pids,
this, joint_name,
221 template<
class StatusType,
class CommandType>
226 ostringstream full_param;
228 int f, p, i,
d, imax, max_pwm, sg_left, sg_right, deadband, sign, torque_limit, torque_limiter_gain;
229 string act_name = boost::to_lower_copy(joint_name);
231 full_param << act_name <<
"/pid/f";
232 this->nodehandle_.template param<int>(full_param.str(), f, 0);
234 full_param << act_name <<
"/pid/p";
235 this->nodehandle_.template param<int>(full_param.str(), p, 0);
237 full_param << act_name <<
"/pid/i";
238 this->nodehandle_.template param<int>(full_param.str(), i, 0);
240 full_param << act_name <<
"/pid/d";
241 this->nodehandle_.template param<int>(full_param.str(), d, 0);
243 full_param << act_name <<
"/pid/imax";
244 this->nodehandle_.template param<int>(full_param.str(), imax, 0);
246 full_param << act_name <<
"/pid/max_pwm";
247 this->nodehandle_.template param<int>(full_param.str(), max_pwm, 0);
249 full_param << act_name <<
"/pid/sgleftref";
250 this->nodehandle_.template param<int>(full_param.str(), sg_left, 0);
252 full_param << act_name <<
"/pid/sgrightref";
253 this->nodehandle_.template param<int>(full_param.str(), sg_right, 0);
255 full_param << act_name <<
"/pid/deadband";
256 this->nodehandle_.template param<int>(full_param.str(), deadband, 0);
258 full_param << act_name <<
"/pid/sign";
259 this->nodehandle_.template param<int>(full_param.str(), sign, 0);
261 full_param << act_name <<
"/pid/torque_limit";
262 this->nodehandle_.template param<int>(full_param.str(), torque_limit, 0);
264 full_param << act_name <<
"/pid/torque_limiter_gain";
265 this->nodehandle_.template param<int>(full_param.str(), torque_limiter_gain, 0);
269 sr_robot_msgs::ForceController::Request pid_request;
270 pid_request.maxpwm = max_pwm;
271 pid_request.sgleftref = sg_left;
272 pid_request.sgrightref = sg_right;
277 pid_request.imax = imax;
278 pid_request.deadband = deadband;
279 pid_request.sign = sign;
280 pid_request.torque_limit = torque_limit;
281 pid_request.torque_limiter_gain = torque_limiter_gain;
282 sr_robot_msgs::ForceController::Response pid_response;
283 bool pid_success = force_pid_callback(pid_request, pid_response, motor_index);
286 bool backlash_compensation;
287 full_param << act_name <<
"/backlash_compensation";
288 this->nodehandle_.template param<bool>(full_param.str(), backlash_compensation,
true);
290 sr_robot_msgs::ChangeMotorSystemControls::Request backlash_request;
291 sr_robot_msgs::MotorSystemControls motor_sys_ctrl;
292 motor_sys_ctrl.motor_id = motor_index;
293 motor_sys_ctrl.enable_backlash_compensation = backlash_compensation;
295 if (!backlash_compensation)
296 ROS_INFO_STREAM(
"Setting backlash compensation to OFF for joint " << act_name);
298 backlash_request.motor_system_controls.push_back(motor_sys_ctrl);
299 sr_robot_msgs::ChangeMotorSystemControls::Response backlash_response;
300 bool backlash_success = this->motor_system_controls_callback_(backlash_request, backlash_response);
303 ROS_WARN_STREAM(
"Didn't load the force pid settings for the motor in joint " << act_name);
304 if (!backlash_success)
305 ROS_WARN_STREAM(
"Didn't set the backlash compensation correctly for the motor in joint " << act_name);
308 template<
class StatusType,
class CommandType>
310 sr_robot_msgs::ForceController::Response &response,
313 ROS_INFO_STREAM(
"Received new force PID parameters for motor " << motor_index);
316 if (motor_index > 20)
319 response.configured =
false;
327 ROS_WARN_STREAM(
" pid parameter maxpwm is out of range : " << request.maxpwm <<
" -> not in [" <<
329 response.configured =
false;
337 ROS_WARN_STREAM(
" pid parameter f is out of range : " << request.f <<
" -> not in [" <<
339 response.configured =
false;
347 ROS_WARN_STREAM(
" pid parameter p is out of range : " << request.p <<
" -> not in [" <<
349 response.configured =
false;
357 ROS_WARN_STREAM(
" pid parameter i is out of range : " << request.i <<
" -> not in [" <<
359 response.configured =
false;
367 ROS_WARN_STREAM(
" pid parameter d is out of range : " << request.d <<
" -> not in [" <<
369 response.configured =
false;
377 ROS_WARN_STREAM(
" pid parameter imax is out of range : " << request.imax <<
" -> not in [" <<
379 response.configured =
false;
387 ROS_WARN_STREAM(
" pid parameter deadband is out of range : " << request.deadband <<
" -> not in [" <<
389 response.configured =
false;
397 ROS_WARN_STREAM(
" pid parameter sign is out of range : " << request.sign <<
" -> not in [" <<
399 response.configured =
false;
406 ROS_WARN_STREAM(
" torque limiter gain out or range : " << request.torque_limiter_gain <<
" -> not in [" <<
409 response.configured =
false;
415 this->generate_force_control_config(motor_index, request.maxpwm, request.sgleftref,
416 request.sgrightref, request.f, request.p, request.i,
417 request.d, request.imax, request.deadband, request.sign,
418 request.torque_limit, request.torque_limiter_gain);
420 update_force_control_in_param_server(find_joint_name(motor_index), request.maxpwm, request.sgleftref,
421 request.sgrightref, request.f, request.p, request.i,
422 request.d, request.imax, request.deadband, request.sign,
423 request.torque_limit, request.torque_limiter_gain);
424 response.configured =
true;
427 this->reinitialize_motors();
432 template<
class StatusType,
class CommandType>
435 for (vector<Joint>::iterator joint = this->joints_vector.begin();
436 joint != this->joints_vector.end();
439 if (joint->has_actuator && static_pointer_cast<MotorWrapper>(joint->actuator_wrapper)->motor_id == motor_index)
441 return joint->joint_name;
444 ROS_ERROR(
"Could not find joint name for motor index: %d", motor_index);
448 template<
class StatusType,
class CommandType>
450 string joint_name,
int max_pwm,
int sg_left,
int sg_right,
int f,
int p,
int i,
451 int d,
int imax,
int deadband,
int sign,
int torque_limit,
int torque_limiter_gain)
453 if (joint_name !=
"")
455 ostringstream full_param;
456 string act_name = boost::to_lower_copy(joint_name);
458 full_param << act_name <<
"/pid/f";
459 this->nodehandle_.setParam(full_param.str(), f);
461 full_param << act_name <<
"/pid/p";
462 this->nodehandle_.setParam(full_param.str(), p);
464 full_param << act_name <<
"/pid/i";
465 this->nodehandle_.setParam(full_param.str(), i);
467 full_param << act_name <<
"/pid/d";
468 this->nodehandle_.setParam(full_param.str(), d);
470 full_param << act_name <<
"/pid/imax";
471 this->nodehandle_.setParam(full_param.str(), imax);
473 full_param << act_name <<
"/pid/max_pwm";
474 this->nodehandle_.setParam(full_param.str(), max_pwm);
476 full_param << act_name <<
"/pid/sgleftref";
477 this->nodehandle_.setParam(full_param.str(), sg_left);
479 full_param << act_name <<
"/pid/sgrightref";
480 this->nodehandle_.setParam(full_param.str(), sg_right);
482 full_param << act_name <<
"/pid/deadband";
483 this->nodehandle_.setParam(full_param.str(), deadband);
485 full_param << act_name <<
"/pid/sign";
486 this->nodehandle_.setParam(full_param.str(), sign);
488 full_param << act_name <<
"/pid/torque_limit";
489 this->nodehandle_.setParam(full_param.str(), torque_limit);
491 full_param << act_name <<
"/pid/torque_limiter_gain";
492 this->nodehandle_.setParam(full_param.str(), torque_limiter_gain);
496 template<
class StatusType,
class CommandType>
499 vector<int> motor_ids;
500 string param_name =
"joint_to_motor_mapping";
503 this->nodehandle_.getParam(param_name, mapping);
506 for (int32_t i = 0; i < mapping.
size(); ++i)
509 motor_ids.push_back(static_cast<int> (mapping[i]));
516 #ifdef DEBUG_PUBLISHER 517 template <
class StatusType,
class CommandType>
519 CommandType>::set_debug_data_to_publish(sr_robot_msgs::SetDebugData::Request& request,
520 sr_robot_msgs::SetDebugData::Response&
response)
523 if (request.publisher_index < this->nb_debug_publishers_const)
527 response.success =
false;
530 if (request.motor_data_type > 0)
533 (request.motor_data_type > MOTOR_DATA_DTERM))
535 response.success =
false;
539 if (!this->debug_mutex.timed_lock(boost::posix_time::microseconds(this->debug_mutex_lock_wait_time)))
541 response.success =
false;
547 this->debug_motor_indexes_and_data[request.publisher_index]->first = request.motor_index;
548 this->debug_motor_indexes_and_data[request.publisher_index]->second = request.motor_data_type;
549 this->debug_mutex.unlock();
553 response.success =
false;
557 response.success =
true;
JointToSensor joint_to_sensor
#define MOTOR_CONFIG_D_RANGE_MAX
ROSCONSOLE_DECL void initialize()
#define MOTOR_CONFIG_IMAX_RANGE_MAX
ServiceServer advertiseService(ros::NodeHandle n, std::string name, boost::function< bool(const typename ActionSpec::_action_goal_type::_goal_type &, typename ActionSpec::_action_result_type::_result_type &result)> service_cb)
#define MOTOR_CONFIG_I_RANGE_MIN
#define MOTOR_CONFIG_D_RANGE_MIN
#define MOTOR_CONFIG_SIGN_RANGE_MAX
#define MOTOR_CONFIG_P_RANGE_MIN
#define MOTOR_DEMAND_TORQUE_LIMITER_GAIN_MIN
MOTOR_DATA_CAN_NUM_RECEIVED
#define MOTOR_CONFIG_P_RANGE_MAX
#define MOTOR_DEMAND_PWM_RANGE_MIN
#define MOTOR_DEMAND_TORQUE_LIMITER_GAIN_MAX
#define MOTOR_DEMAND_PWM_RANGE_MAX
#define MOTOR_CONFIG_F_RANGE_MAX
Type const & getType() const
#define MOTOR_CONFIG_F_RANGE_MIN
#define MOTOR_CONFIG_DEADBAND_RANGE_MIN
#define MOTOR_CONFIG_DEADBAND_RANGE_MAX
sr_math_utils::filters::LowPassFilter pos_filter
MOTOR_DATA_CAN_ERROR_COUNTERS
#define MOTOR_CONFIG_SIGN_RANGE_MIN
static const int nb_motor_data
MOTOR_DATA_CAN_NUM_TRANSMITTED
#define ROS_WARN_STREAM(args)
boost::shared_ptr< SrActuatorWrapper > actuator_wrapper
#define ROS_INFO_STREAM(args)
static const int32u motor_data_types[]
#define MOTOR_CONFIG_I_RANGE_MAX
SrMotorHandLib(hardware_interface::HardwareInterface *hw, ros::NodeHandle nh, ros::NodeHandle nhtilde, std::string device_id, std::string joint_prefix)
#define MOTOR_CONFIG_IMAX_RANGE_MIN
const std::string response