45 const static double EPS = 1e-5;
47 Pr2BaseController2::Pr2BaseController2()
50 cmd_vel_.linear.x = 0;
51 cmd_vel_.linear.y = 0;
52 cmd_vel_.angular.z = 0;
54 desired_vel_.linear.x = 0;
55 desired_vel_.linear.y = 0;
56 desired_vel_.angular.z = 0;
58 cmd_vel_t_.linear.x = 0;
59 cmd_vel_t_.linear.y = 0;
60 cmd_vel_t_.angular.z = 0;
62 new_cmd_available_ =
false;
65 pthread_mutex_init(&pr2_base_controller_lock_, NULL);
68 Pr2BaseController2::~Pr2BaseController2()
71 cmd_sub_deprecated_.shutdown();
76 if(!base_kinematics_.init(robot,n))
81 int num_joints = base_kinematics_.num_wheels_ + base_kinematics_.num_casters_;
82 state_publisher_->msg_.joint_names.resize(num_joints);
83 state_publisher_->msg_.joint_velocity_commanded.resize(num_joints);
84 state_publisher_->msg_.joint_velocity_measured.resize(num_joints);
85 state_publisher_->msg_.joint_effort_measured.resize(num_joints);
86 state_publisher_->msg_.joint_command.resize(num_joints);
87 state_publisher_->msg_.joint_effort_commanded.resize(num_joints);
88 state_publisher_->msg_.joint_error.resize(num_joints);
89 state_publisher_->msg_.joint_effort_error.resize(num_joints);
92 node_.
param<
double> (
"max_translational_velocity", max_translational_velocity_,0.5);
93 node_.param<
double> (
"max_rotational_velocity", max_rotational_velocity_, 10.0);
94 node_.param<
double> (
"max_translational_acceleration/x", max_accel_.linear.x, .2);
95 node_.param<
double> (
"max_translational_acceleration/y", max_accel_.linear.y, .2);
96 node_.param<
double> (
"max_rotational_acceleration", max_accel_.angular.z, 10.0);
98 node_.param<
double> (
"kp_caster_steer", kp_caster_steer_, 80.0);
99 node_.param<
double> (
"timeout", timeout_, 1.0);
100 node_.param<
double> (
"state_publish_rate", state_publish_rate_,2.0);
101 if(state_publish_rate_ <= 0.0)
103 publish_state_ =
false;
104 state_publish_time_ = 0.0;
108 publish_state_ =
true;
109 state_publish_time_ = 1.0/state_publish_rate_;
113 cmd_sub_ = node_.subscribe<geometry_msgs::Twist>(
"command", 1, &Pr2BaseController2::commandCallback,
this);
116 caster_controller_.resize(base_kinematics_.num_casters_);
117 caster_position_pid_.resize(base_kinematics_.num_casters_);
118 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
121 state_publisher_->msg_.joint_names[i] = base_kinematics_.caster_[i].joint_name_;
122 if(!p_i_d.
init(
ros::NodeHandle(node_, base_kinematics_.caster_[i].joint_name_+
"/velocity_controller")))
124 ROS_ERROR(
"Could not initialize pid for %s",base_kinematics_.caster_[i].joint_name_.c_str());
128 if(!caster_position_pid_[i].init(
ros::NodeHandle(node_, base_kinematics_.caster_[i].joint_name_+
"/position_controller")))
130 ROS_ERROR(
"Could not initialize position pid controller for %s",base_kinematics_.caster_[i].joint_name_.c_str());
134 if(!caster_controller_[i]->init(base_kinematics_.robot_state_, base_kinematics_.caster_[i].joint_name_, p_i_d))
136 ROS_ERROR(
"Could not initialize pid for %s",base_kinematics_.caster_[i].joint_name_.c_str());
139 if (!caster_controller_[i]->joint_state_->calibrated_)
141 ROS_ERROR(
"Caster joint \"%s\" not calibrated (namespace: %s)",
142 base_kinematics_.caster_[i].joint_name_.c_str(), node_.getNamespace().c_str());
147 wheel_pid_controllers_.resize(base_kinematics_.num_wheels_);
149 for(
int j = 0; j < base_kinematics_.num_wheels_; j++)
152 state_publisher_->msg_.joint_names[j + base_kinematics_.num_casters_] = base_kinematics_.wheel_[j].joint_name_;
153 if(!wheel_pid_controllers_[j].init(
ros::NodeHandle(node_,base_kinematics_.wheel_[j].joint_name_)))
155 ROS_ERROR(
"Could not initialize pid for %s",base_kinematics_.wheel_[j].joint_name_.c_str());
165 for(
int i = 0; i < base_kinematics_.num_casters_; ++i)
167 if(!base_kinematics_.caster_[i].joint_->calibrated_)
169 ROS_ERROR(
"The Base controller could not start because the casters were not calibrated. Relaunch the base controller after you see the caster calibration finish.");
175 ROS_ERROR(
"BaseController: could not configure velocity filters for casters");
179 ROS_ERROR(
"BaseController: could not configure velocity filters for wheels");
182 filtered_velocity_.resize(base_kinematics_.num_casters_);
183 filtered_wheel_velocity_.resize(base_kinematics_.num_wheels_);
188 void Pr2BaseController2::setCommand(
const geometry_msgs::Twist &cmd_vel)
190 double vel_mag =
sqrt(cmd_vel.linear.x * cmd_vel.linear.x + cmd_vel.linear.y * cmd_vel.linear.y);
191 double clamped_vel_mag =
filters::clamp(vel_mag,-max_translational_velocity_, max_translational_velocity_);
194 cmd_vel_t_.linear.x = cmd_vel.linear.x * clamped_vel_mag / vel_mag;
195 cmd_vel_t_.linear.y = cmd_vel.linear.y * clamped_vel_mag / vel_mag;
199 cmd_vel_t_.linear.x = 0.0;
200 cmd_vel_t_.linear.y = 0.0;
202 cmd_vel_t_.angular.z =
filters::clamp(cmd_vel.angular.z, -max_rotational_velocity_, max_rotational_velocity_);
203 cmd_received_timestamp_ = base_kinematics_.robot_state_->getTime();
205 ROS_DEBUG(
"BaseController:: command received: %f %f %f",cmd_vel.linear.x,cmd_vel.linear.y,cmd_vel.angular.z);
206 ROS_DEBUG(
"BaseController:: command current: %f %f %f", cmd_vel_.linear.x,cmd_vel_.linear.y,cmd_vel_.angular.z);
207 ROS_DEBUG(
"BaseController:: clamped vel: %f", clamped_vel_mag);
208 ROS_DEBUG(
"BaseController:: vel: %f", vel_mag);
210 for(
int i=0; i < (int) base_kinematics_.num_wheels_; i++)
212 ROS_DEBUG(
"BaseController:: wheel speed cmd:: %d %f",i,(base_kinematics_.wheel_[i].direction_multiplier_*base_kinematics_.wheel_[i].wheel_speed_cmd_));
214 for(
int i=0; i < (int) base_kinematics_.num_casters_; i++)
216 ROS_DEBUG(
"BaseController:: caster speed cmd:: %d %f",i,(base_kinematics_.caster_[i].steer_velocity_desired_));
218 new_cmd_available_ =
true;
221 geometry_msgs::Twist Pr2BaseController2::interpolateCommand(
const geometry_msgs::Twist &start,
const geometry_msgs::Twist &end,
const geometry_msgs::Twist &max_rate,
const double &dT)
223 geometry_msgs::Twist result;
224 geometry_msgs::Twist alpha;
225 double delta(0), max_delta(0);
227 delta = end.linear.x - start.linear.x;
228 max_delta = max_rate.linear.x * dT;
229 if(fabs(delta) <= max_delta || max_delta < EPS)
232 alpha.linear.x = max_delta / fabs(delta);
234 delta = end.linear.y - start.linear.y;
235 max_delta = max_rate.linear.y * dT;
236 if(fabs(delta) <= max_delta || max_delta < EPS)
239 alpha.linear.y = max_delta / fabs(delta);
241 delta = end.angular.z - start.angular.z;
242 max_delta = max_rate.angular.z * dT;
243 if(fabs(delta) <= max_delta || max_delta < EPS)
246 alpha.angular.z = max_delta / fabs(delta);
248 double alpha_min = alpha.linear.x;
249 if(alpha.linear.y < alpha_min)
250 alpha_min = alpha.linear.y;
251 if(alpha.angular.z < alpha_min)
252 alpha_min = alpha.angular.z;
254 result.linear.x = start.linear.x + alpha_min * (end.linear.x - start.linear.x);
255 result.linear.y = start.linear.y + alpha_min * (end.linear.y - start.linear.y);
256 result.angular.z = start.angular.z + alpha_min * (end.angular.z - start.angular.z);
260 geometry_msgs::Twist Pr2BaseController2::getCommand()
262 geometry_msgs::Twist cmd_vel;
263 pthread_mutex_lock(&pr2_base_controller_lock_);
264 cmd_vel.linear.x = cmd_vel_.linear.x;
265 cmd_vel.linear.y = cmd_vel_.linear.y;
266 cmd_vel.angular.z = cmd_vel_.angular.z;
267 pthread_mutex_unlock(&pr2_base_controller_lock_);
271 void Pr2BaseController2::starting()
273 last_time_ = base_kinematics_.robot_state_->getTime();
274 cmd_received_timestamp_ = base_kinematics_.robot_state_->getTime();
275 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
277 caster_controller_[i]->starting();
279 for(
int j = 0; j < base_kinematics_.num_wheels_; j++)
285 void Pr2BaseController2::update()
287 ros::Time current_time = base_kinematics_.robot_state_->getTime();
288 double dT = std::min<double>((current_time - last_time_).toSec(), base_kinematics_.MAX_DT_);
290 if(new_cmd_available_)
292 if(pthread_mutex_trylock(&pr2_base_controller_lock_) == 0)
294 desired_vel_.linear.x = cmd_vel_t_.linear.x;
295 desired_vel_.linear.y = cmd_vel_t_.linear.y;
296 desired_vel_.angular.z = cmd_vel_t_.angular.z;
297 new_cmd_available_ =
false;
298 pthread_mutex_unlock(&pr2_base_controller_lock_);
302 if((current_time - cmd_received_timestamp_).toSec() > timeout_)
304 cmd_vel_.linear.x = 0;
305 cmd_vel_.linear.y = 0;
306 cmd_vel_.angular.z = 0;
309 cmd_vel_ = interpolateCommand(cmd_vel_, desired_vel_, max_accel_, dT);
311 computeJointCommands(dT);
315 updateJointControllers();
318 publishState(current_time);
320 last_time_ = current_time;
324 void Pr2BaseController2::publishState(
const ros::Time &time)
326 if((time - last_publish_time_).toSec() < state_publish_time_)
331 if(state_publisher_->trylock())
333 state_publisher_->msg_.command.linear.x = cmd_vel_.linear.x;
334 state_publisher_->msg_.command.linear.y = cmd_vel_.linear.y;
335 state_publisher_->msg_.command.angular.z = cmd_vel_.angular.z;
337 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
339 state_publisher_->msg_.joint_names[i] = base_kinematics_.caster_[i].joint_name_;
340 state_publisher_->msg_.joint_velocity_measured[i] = base_kinematics_.caster_[i].joint_->velocity_;
341 state_publisher_->msg_.joint_command[i]= base_kinematics_.caster_[i].steer_angle_desired_;
342 state_publisher_->msg_.joint_error[i] = base_kinematics_.caster_[i].joint_->position_ - base_kinematics_.caster_[i].steer_angle_desired_;
344 state_publisher_->msg_.joint_effort_measured[i] = base_kinematics_.caster_[i].joint_->measured_effort_;
345 state_publisher_->msg_.joint_effort_commanded[i] = base_kinematics_.caster_[i].joint_->commanded_effort_;
346 state_publisher_->msg_.joint_effort_error[i] = base_kinematics_.caster_[i].joint_->measured_effort_ - base_kinematics_.caster_[i].joint_->commanded_effort_;
348 for(
int i = 0; i < base_kinematics_.num_wheels_; i++)
350 state_publisher_->msg_.joint_names[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].joint_name_;
351 state_publisher_->msg_.joint_velocity_commanded[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].wheel_speed_cmd_;
352 state_publisher_->msg_.joint_velocity_measured[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].joint_->velocity_;
353 state_publisher_->msg_.joint_command[i+base_kinematics_.num_casters_]= base_kinematics_.wheel_[i].joint_->velocity_-base_kinematics_.wheel_[i].wheel_speed_cmd_;
354 state_publisher_->msg_.joint_error[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].wheel_speed_cmd_;
356 state_publisher_->msg_.joint_effort_measured[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].joint_->measured_effort_;
357 state_publisher_->msg_.joint_effort_commanded[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].joint_->commanded_effort_;
358 state_publisher_->msg_.joint_effort_error[i+base_kinematics_.num_casters_] = base_kinematics_.wheel_[i].joint_->measured_effort_ - base_kinematics_.wheel_[i].joint_->commanded_effort_;
360 state_publisher_->unlockAndPublish();
361 last_publish_time_ = time;
365 void Pr2BaseController2::computeJointCommands(
const double &dT)
367 base_kinematics_.computeWheelPositions();
369 computeDesiredCasterSteer(dT);
371 computeDesiredWheelSpeeds(dT);
374 void Pr2BaseController2::setJointCommands()
376 setDesiredCasterSteer();
378 setDesiredWheelSpeeds();
381 void Pr2BaseController2::computeDesiredCasterSteer(
const double &dT)
383 geometry_msgs::Twist result;
385 double steer_angle_desired(0.0), steer_angle_desired_m_pi(0.0);
386 double error_steer(0.0), error_steer_m_pi(0.0);
387 double trans_vel =
sqrt(cmd_vel_.linear.x * cmd_vel_.linear.x + cmd_vel_.linear.y * cmd_vel_.linear.y);
389 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
391 filtered_velocity_[i] = 0.0 - base_kinematics_.caster_[i].joint_->velocity_;
393 caster_vel_filter_.update(filtered_velocity_,filtered_velocity_);
395 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
397 result = base_kinematics_.pointVel2D(base_kinematics_.caster_[i].offset_, cmd_vel_);
398 if(trans_vel < EPS && fabs(cmd_vel_.angular.z) < EPS)
400 steer_angle_desired = base_kinematics_.caster_[i].steer_angle_stored_;
404 steer_angle_desired =
atan2(result.linear.y, result.linear.x);
405 base_kinematics_.caster_[i].steer_angle_stored_ = steer_angle_desired;
409 base_kinematics_.caster_[i].joint_->position_,
410 steer_angle_desired);
412 base_kinematics_.caster_[i].joint_->position_,
413 steer_angle_desired_m_pi);
415 if(fabs(error_steer_m_pi) < fabs(error_steer))
417 error_steer = error_steer_m_pi;
418 steer_angle_desired = steer_angle_desired_m_pi;
420 base_kinematics_.caster_[i].steer_angle_desired_ = steer_angle_desired;
421 double command = caster_position_pid_[i].computeCommand(error_steer,
423 base_kinematics_.caster_[i].joint_->commanded_effort_ = command;
425 base_kinematics_.caster_[i].caster_position_error_ = error_steer;
429 void Pr2BaseController2::setDesiredCasterSteer()
431 for(
int i = 0; i < base_kinematics_.num_casters_; i++)
437 void Pr2BaseController2::computeDesiredWheelSpeeds(
const double &dT)
439 geometry_msgs::Twist wheel_point_velocity;
440 geometry_msgs::Twist wheel_point_velocity_projected;
441 geometry_msgs::Twist wheel_caster_steer_component;
442 geometry_msgs::Twist caster_2d_velocity;
444 caster_2d_velocity.linear.x = 0;
445 caster_2d_velocity.linear.y = 0;
446 caster_2d_velocity.angular.z = 0;
448 for(
int i = 0; i < base_kinematics_.num_wheels_; i++)
450 filtered_wheel_velocity_[i] = base_kinematics_.wheel_[i].joint_->velocity_;
452 wheel_vel_filter_.update(filtered_wheel_velocity_,filtered_wheel_velocity_);
454 double steer_angle_actual = 0;
455 for(
int i = 0; i < (int) base_kinematics_.num_wheels_; i++)
457 base_kinematics_.wheel_[i].updatePosition();
459 caster_2d_velocity.angular.z = 0.0 - base_kinematics_.wheel_[i].parent_->caster_position_error_;
460 steer_angle_actual = base_kinematics_.wheel_[i].parent_->joint_->position_;
461 wheel_point_velocity = base_kinematics_.pointVel2D(base_kinematics_.wheel_[i].position_, cmd_vel_);
462 wheel_caster_steer_component = base_kinematics_.pointVel2D(base_kinematics_.wheel_[i].offset_, caster_2d_velocity);
464 double costh =
cos(-steer_angle_actual);
465 double sinth =
sin(-steer_angle_actual);
467 wheel_point_velocity_projected.linear.x = costh * wheel_point_velocity.linear.x - sinth * wheel_point_velocity.linear.y;
468 wheel_point_velocity_projected.linear.y = sinth * wheel_point_velocity.linear.x + costh * wheel_point_velocity.linear.y;
469 base_kinematics_.wheel_[i].wheel_speed_cmd_ = (wheel_point_velocity_projected.linear.x) / (base_kinematics_.wheel_[i].wheel_radius_);
470 double command = wheel_pid_controllers_[i].computeCommand(
471 - wheel_caster_steer_component.linear.x/base_kinematics_.wheel_[i].wheel_radius_,
472 base_kinematics_.wheel_[i].wheel_speed_cmd_ - filtered_wheel_velocity_[i],
474 base_kinematics_.wheel_[i].joint_->commanded_effort_ = command;
478 void Pr2BaseController2::setDesiredWheelSpeeds()
486 void Pr2BaseController2::updateJointControllers()
494 void Pr2BaseController2::commandCallback(
const geometry_msgs::TwistConstPtr& msg)
496 pthread_mutex_lock(&pr2_base_controller_lock_);
497 base_vel_msg_ = *msg;
498 this->setCommand(base_vel_msg_);
499 pthread_mutex_unlock(&pr2_base_controller_lock_);
PLUGINLIB_EXPORT_CLASS(my_controller_ns::MyControllerClass, pr2_controller_interface::Controller)
ROSLIB_DECL std::string command(const std::string &cmd)
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
static const T & clamp(const T &a, const T &b, const T &c)
INLINE Rall1d< T, V, S > sqrt(const Rall1d< T, V, S > &arg)
def normalize_angle(angle)
INLINE Rall1d< T, V, S > atan2(const Rall1d< T, V, S > &y, const Rall1d< T, V, S > &x)
INLINE Rall1d< T, V, S > cos(const Rall1d< T, V, S > &arg)
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
def shortest_angular_distance(from_angle, to_angle)