Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 #include <effort_controllers/joint_position_controller.h>
00043 #include <angles/angles.h>
00044 #include <pluginlib/class_list_macros.h>
00045 
00046 namespace effort_controllers {
00047 
00048 JointPositionController::JointPositionController()
00049   : loop_count_(0)
00050 {}
00051 
00052 JointPositionController::~JointPositionController()
00053 {
00054   sub_command_.shutdown();
00055 }
00056 
00057 bool JointPositionController::init(hardware_interface::EffortJointInterface *robot, ros::NodeHandle &n)
00058 {
00059   
00060   std::string joint_name;
00061   if (!n.getParam("joint", joint_name)) 
00062   {
00063     ROS_ERROR("No joint given (namespace: %s)", n.getNamespace().c_str());
00064     return false;
00065   }
00066 
00067   
00068   if (!pid_controller_.init(ros::NodeHandle(n, "pid")))
00069     return false;
00070 
00071   
00072   controller_state_publisher_.reset(
00073     new realtime_tools::RealtimePublisher<control_msgs::JointControllerState>(n, "state", 1));
00074 
00075   
00076   sub_command_ = n.subscribe<std_msgs::Float64>("command", 1, &JointPositionController::setCommandCB, this);
00077 
00078   
00079   joint_ = robot->getHandle(joint_name);
00080 
00081   
00082   urdf::Model urdf;
00083   if (!urdf.initParam("robot_description"))
00084   {
00085     ROS_ERROR("Failed to parse urdf file");
00086     return false;
00087   }
00088   joint_urdf_ = urdf.getJoint(joint_name);
00089   if (!joint_urdf_)
00090   {
00091     ROS_ERROR("Could not find joint '%s' in urdf", joint_name.c_str());
00092     return false;
00093   }
00094 
00095   return true;
00096 }
00097 
00098 void JointPositionController::setGains(const double &p, const double &i, const double &d, const double &i_max, const double &i_min)
00099 {
00100   pid_controller_.setGains(p,i,d,i_max,i_min);
00101 }
00102 
00103 void JointPositionController::getGains(double &p, double &i, double &d, double &i_max, double &i_min)
00104 {
00105   pid_controller_.getGains(p,i,d,i_max,i_min);
00106 }
00107 
00108 void JointPositionController::printDebug()
00109 {
00110   pid_controller_.printValues();
00111 }
00112 
00113 std::string JointPositionController::getJointName()
00114 {
00115   return joint_.getName();
00116 }
00117 
00118 double JointPositionController::getPosition()
00119 {
00120   return joint_.getPosition();
00121 }
00122 
00123 
00124 void JointPositionController::setCommand(double pos_command)
00125 {
00126   command_struct_.position_ = pos_command;
00127   command_struct_.has_velocity_ = false; 
00128 
00129   
00130   
00131   
00132   command_.writeFromNonRT(command_struct_);
00133 }
00134 
00135 
00136 void JointPositionController::setCommand(double pos_command, double vel_command)
00137 {
00138   command_struct_.position_ = pos_command;
00139   command_struct_.velocity_ = vel_command;
00140   command_struct_.has_velocity_ = true;
00141 
00142   command_.writeFromNonRT(command_struct_);
00143 }
00144 
00145 void JointPositionController::starting(const ros::Time& time)
00146 {
00147   double pos_command = joint_.getPosition();
00148 
00149   
00150   enforceJointLimits(pos_command);
00151 
00152   command_struct_.position_ = pos_command;
00153   command_struct_.has_velocity_ = false;
00154 
00155   command_.initRT(command_struct_);
00156 
00157   pid_controller_.reset();
00158 }
00159 
00160 void JointPositionController::update(const ros::Time& time, const ros::Duration& period)
00161 {
00162   command_struct_ = *(command_.readFromRT());
00163   double command_position = command_struct_.position_;
00164   double command_velocity = command_struct_.velocity_;
00165   bool has_velocity_ =  command_struct_.has_velocity_;
00166 
00167   double error, vel_error;
00168   double commanded_effort;
00169 
00170   double current_position = joint_.getPosition();
00171 
00172   
00173   enforceJointLimits(command_position);
00174 
00175   
00176   if (joint_urdf_->type == urdf::Joint::REVOLUTE)
00177   {
00178    angles::shortest_angular_distance_with_limits(
00179       current_position,
00180       command_position,
00181       joint_urdf_->limits->lower,
00182       joint_urdf_->limits->upper,
00183       error);
00184   }
00185   else if (joint_urdf_->type == urdf::Joint::CONTINUOUS)
00186   {
00187     error = angles::shortest_angular_distance(current_position, command_position);
00188   }
00189   else 
00190   {
00191     error = command_position - current_position;
00192   }
00193 
00194   
00195   if (has_velocity_)
00196   {
00197     
00198     vel_error = command_velocity - joint_.getVelocity();
00199 
00200     
00201     
00202     commanded_effort = pid_controller_.computeCommand(error, vel_error, period);
00203   }
00204   else
00205   {
00206     
00207     
00208     commanded_effort = pid_controller_.computeCommand(error, period);
00209   }
00210 
00211   joint_.setCommand(commanded_effort);
00212 
00213   
00214   if (loop_count_ % 10 == 0)
00215   {
00216     if(controller_state_publisher_ && controller_state_publisher_->trylock())
00217     {
00218       controller_state_publisher_->msg_.header.stamp = time;
00219       controller_state_publisher_->msg_.set_point = command_position;
00220       controller_state_publisher_->msg_.process_value = current_position;
00221       controller_state_publisher_->msg_.process_value_dot = joint_.getVelocity();
00222       controller_state_publisher_->msg_.error = error;
00223       controller_state_publisher_->msg_.time_step = period.toSec();
00224       controller_state_publisher_->msg_.command = commanded_effort;
00225 
00226       double dummy;
00227       getGains(controller_state_publisher_->msg_.p,
00228         controller_state_publisher_->msg_.i,
00229         controller_state_publisher_->msg_.d,
00230         controller_state_publisher_->msg_.i_clamp,
00231         dummy);
00232       controller_state_publisher_->unlockAndPublish();
00233     }
00234   }
00235   loop_count_++;
00236 }
00237 
00238 void JointPositionController::setCommandCB(const std_msgs::Float64ConstPtr& msg)
00239 {
00240   setCommand(msg->data);
00241 }
00242 
00243 
00244 void JointPositionController::enforceJointLimits(double &command)
00245 {
00246   
00247   if (joint_urdf_->type == urdf::Joint::REVOLUTE || joint_urdf_->type == urdf::Joint::PRISMATIC)
00248   {
00249     if( command > joint_urdf_->limits->upper ) 
00250     {
00251       command = joint_urdf_->limits->upper;
00252     }
00253     else if( command < joint_urdf_->limits->lower ) 
00254     {
00255       command = joint_urdf_->limits->lower;
00256     }
00257   }
00258 }
00259 
00260 } 
00261 
00262 PLUGINLIB_EXPORT_CLASS( effort_controllers::JointPositionController, controller_interface::ControllerBase)