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
00039 #include <pluginlib/class_list_macros.h>
00040 #include "joint_position_controller/joint_position_controller.h"
00041
00042
00043 static const std::string SUB_TOPIC_JOINT_STATES_CMD = "/joint_states_cmd";
00044
00045
00046 void JointPositionController::jointStatesCmdCB(const sensor_msgs::JointState::ConstPtr &command)
00047 {
00048 if (command->position.size() == q_desi_.rows())
00049 {
00050 for(unsigned int i = 0; i < q_desi_.rows(); ++i)
00051 {
00052 q_desi_(i) = command->position[i];
00053 }
00054 }
00055 else
00056 ROS_WARN("Size of the commanded joint state does not match the internally used size of the joint array!");
00057 ROS_WARN("Desired joint positions are not updated!");
00058 }
00059
00060
00061
00062 bool JointPositionController::init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &node)
00063 {
00064
00065 robot_state_ = robot;
00066
00067
00068 tree_.init(robot_state_);
00069
00070
00071 nrOfJnts_ = tree_.size();
00072 q_.resize(nrOfJnts_);
00073 q_desi_.resize(nrOfJnts_);
00074 q_err_.resize(nrOfJnts_);
00075 q_err_old_.resize(nrOfJnts_);
00076 q_err_dot_.resize(nrOfJnts_);
00077 tau_.resize(nrOfJnts_);
00078 tau_max_.resize(nrOfJnts_);
00079 Kp_.resize(nrOfJnts_);
00080 Kd_.resize(nrOfJnts_);
00081
00082
00083 node.param("limit_error", limit_error_, false);
00084 ROS_INFO("limit_error = %s", (limit_error_)?"true":"false");
00085
00086
00087 double factor;
00088 node.param("q_err_max_factor", factor, 0.0);
00089 node.param("q_err_max", q_err_max_, 0.0);
00090 ROS_INFO("q_err_max_ = %f", q_err_max_);
00091
00092
00093 node.param("q_err_dot_max_factor", factor, 0.0);
00094 q_err_dot_max_ = factor * q_err_max_;
00095 ROS_INFO("q_err_dot_max_ = %f", q_err_dot_max_);
00096
00098 double PGain, DGain, DGainFactor;
00099 node.param("PGain", PGain, 0.0);
00100 ROS_INFO("PGain = %f", PGain);
00101 node.param("DGainFactor", DGainFactor, 0.0);
00102 node.param("DGain", DGain, 0.0);
00103 ROS_INFO("DGain = %f", DGain);
00104 for (unsigned int i = 0 ; i < nrOfJnts_ ; ++i)
00105 {
00106 Kp_(i) = 0.5 * PGain;
00107 Kd_(i) = 0.5 * DGain;
00108 }
00109 for (unsigned int i = 0 ; i < nrOfJnts_; ++i)
00110 {
00111 std::string name_str;
00112 std::stringstream ss;
00113 ss << "Kp_" << i;
00114 ss >> name_str;
00115 double factor;
00116 node.getParam(name_str, factor);
00117 Kp_(i) = factor * PGain;
00118 ROS_INFO("Kp_(%d) = %f", i, Kp_(i));
00119 ss << "Kd_" << i;
00120 ss >> name_str;
00121 node.getParam(name_str, factor);
00122 Kd_(i) = factor * DGain;
00123 ROS_INFO("Kd_(%d) = %f", i, Kd_(i));
00124 }
00125
00126 double tau_max_value;
00127 node.param("tau_max_value", tau_max_value, 100.0);
00128 for (unsigned int i = 0 ; i < nrOfJnts_; ++i)
00129 {
00130 std::string name_str;
00131 std::stringstream ss;
00132 ss << "tau_max_factor_" << i;
00133 ss >> name_str;
00134 double factor;
00135 node.param(name_str, factor, 0.0);
00136 tau_max_(i) = factor * tau_max_value;
00137 ROS_INFO("tau_max_(%d) = %f", i, tau_max_(i));
00138 }
00139
00140
00141 sub_joint_states_cmd = node.subscribe(SUB_TOPIC_JOINT_STATES_CMD, 20, &JointPositionController::jointStatesCmdCB, this);
00142
00143 return true;
00144 }
00145
00146
00147
00148 void JointPositionController::starting()
00149 {
00150 loop_count_ = 0;
00151 last_time_ = robot_state_->getTime();
00152 dt_ = 0.0;
00153
00154 for (unsigned int i = 0; i < nrOfJnts_; ++i)
00155 {
00156 q_(i) = q_desi_(i) = q_err_(i) = q_err_old_(i) = q_err_dot_(i) = tau_(i) = 0.0;
00157 }
00158 }
00159
00160
00161
00162 void JointPositionController::update()
00163 {
00164 if (loop_count_ % 1000 == 0)
00165 {
00166 ROS_DEBUG("-----------------------------------UPDATING_START--------------------------------------");
00167 ROS_DEBUG("loop_count_ = %d", loop_count_);
00168 }
00169
00170
00171 tree_.getPositions(q_);
00172
00173
00174 dt_ = (robot_state_->getTime() - last_time_).toSec();
00175 last_time_ = robot_state_->getTime();
00176 if (loop_count_ % 1000 == 0)
00177 ROS_DEBUG("dt_ = %f", dt_);
00178
00179
00180 KDL::Subtract(q_desi_, q_, q_err_);
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193 double rel_os, rel_os_max = 0.0;
00194 bool max_exceeded = false;
00195
00196 if(limit_error_ == true)
00197 {
00198 ROS_DEBUG_THROTTLE(1.0, "limitting");
00199 for (unsigned int i = 0; i < q_err_.rows(); ++i)
00200 {
00201 if ( q_err_(i) > q_err_max_ )
00202 {
00203 max_exceeded = true;
00204 rel_os = (q_err_(i) - q_err_max_) / q_err_max_;
00205 if ( rel_os > rel_os_max )
00206 {
00207 rel_os_max = rel_os;
00208 }
00209 }
00210 else if ( q_err_(i) < -q_err_max_ )
00211 {
00212 max_exceeded = true;
00213 rel_os = (-q_err_(i) - q_err_max_) / q_err_max_;
00214 if ( rel_os > rel_os_max)
00215 {
00216 rel_os_max = rel_os;
00217 }
00218 }
00219 }
00220
00221 if ( max_exceeded == true )
00222 KDL::Multiply(q_err_, ( 1.0 / ( 1.0 + rel_os_max ) ), q_err_);
00223 }
00224
00225
00226 KDL::Subtract(q_err_, q_err_old_, q_err_dot_);
00227 q_err_old_ = q_err_;
00228
00229
00230 for (unsigned int i = 0; i < nrOfJnts_; ++i)
00231 tau_(i) = Kp_(i) * q_err_(i) + Kd_(i) * q_err_dot_(i);
00232
00233
00234 for (unsigned int i = 0; i < nrOfJnts_; ++i)
00235 {
00236 if (tau_(i) > tau_max_(i))
00237 tau_(i) = tau_max_(i);
00238 else if (tau_(i) < -tau_max_(i))
00239 tau_(i) = -tau_max_(i);
00240 }
00241
00242
00243 tree_.setEfforts(tau_);
00244
00245 if (loop_count_ % 1000 == 0)
00246 {
00247 ROS_DEBUG("tree joint controller statistics:");
00248 for (unsigned int i = 0; i < q_.rows(); ++i)
00249 {
00250 ROS_DEBUG("q_[%d]: %f, q_desi_[%d]: %f, q_err_[%d]: %f, q_err_dot_[%d]: %f, tau_[%d]: %f",
00251 i, q_(i), i, q_desi_(i), i, q_err_(i), i, q_err_dot_(i), i, tau_(i));
00252 }
00253 ROS_DEBUG("-----------------------------------UPDATING_END--------------------------------------");
00254 }
00255
00256 loop_count_++;
00257 }
00258
00259
00260
00261 void JointPositionController::stopping()
00262 {}
00263
00264
00266 PLUGINLIB_DECLARE_CLASS(joint_position_controller, JointPositionController, JointPositionController, pr2_controller_interface::Controller)