$search
00001 /********************************************************************* 00002 * 00003 * Software License Agreement (BSD License) 00004 * 00005 * Copyright (c) 2011, Robert Bosch LLC. 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above 00015 * copyright notice, this list of conditions and the following 00016 * disclaimer in the documentation and/or other materials provided 00017 * with the distribution. 00018 * * Neither the name of the Robert Bosch nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00032 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 * POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 *********************************************************************/ 00036 00037 #include "pr2_dremel_arm_controller/joint_force_controller.h" 00038 #include "angles/angles.h" 00039 #include "pluginlib/class_list_macros.h" 00040 00041 PLUGINLIB_DECLARE_CLASS(pr2_dremel, JointForceController, pr2_dremel::JointForceController, pr2_controller_interface::Controller) 00042 00043 namespace pr2_dremel { 00044 00045 double sign(double v) { 00046 if (v < 0.0) 00047 return -1.0; 00048 return 1.0; 00049 } 00050 00051 JointForceController::JointForceController() 00052 : initialized_(false), robot_(NULL), last_time_(0), joint_state_(NULL), 00053 force_control_(true), force_(0.0), position_(0.0), max_velocity_(0.1), 00054 position_control_limit_(0.03) 00055 { 00056 reset_velocity_average(); 00057 } 00058 00059 JointForceController::~JointForceController() 00060 { 00061 force_sub_.shutdown(); 00062 position_sub_.shutdown(); 00063 } 00064 00065 void JointForceController::reset_velocity_average() 00066 { 00067 velocity_id_ = 0; 00068 velocity_sum_ = 0.0; 00069 for (int i=0; i < velocity_window_; i++) { 00070 velocities_[i] = 0.0; 00071 } 00072 } 00073 00074 bool JointForceController::init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n) 00075 { 00076 assert(robot); 00077 node_ = n; 00078 robot_ = robot; 00079 00080 std::string joint_name; 00081 if (!node_.getParam("joint", joint_name)) 00082 { 00083 ROS_ERROR("No joint given (namespace: %s)", node_.getNamespace().c_str()); 00084 return false; 00085 } 00086 00087 if (!(joint_state_ = robot_->getJointState(joint_name))) 00088 { 00089 ROS_ERROR("Could not find joint \"%s\" (namespace: %s)", 00090 joint_name.c_str(), node_.getNamespace().c_str()); 00091 return false; 00092 } 00093 00094 if (!position_pid_controller_.init(ros::NodeHandle(node_, "position/pid"))) 00095 return false; 00096 00097 if (!velocity_pid_controller_.init(ros::NodeHandle(node_, "velocity/pid"))) 00098 return false; 00099 00100 node_.param("max_velocity", max_velocity_, 0.1); 00101 node_.param("position_control_limit", position_control_limit_, 0.03); 00102 00103 force_sub_ = node_.subscribe<std_msgs::Float64>("force", 1, &JointForceController::forceCB, this); 00104 position_sub_ = node_.subscribe<std_msgs::Float64>("position", 1, &JointForceController::positionCB, this); 00105 // vel_pub_ = node_.advertise<std_msgs::Float64>("avg_vel", 10); 00106 00107 return true; 00108 } 00109 00110 void JointForceController::starting() { 00111 force_control_ = true; 00112 force_ = 0.0; 00113 position_ = joint_state_->position_; 00114 position_pid_controller_.reset(); 00115 velocity_pid_controller_.reset(); 00116 00117 reset_velocity_average(); 00118 00119 initialized_ = true; 00120 } 00121 00122 void JointForceController::update() 00123 { 00124 assert(robot_ != NULL); 00125 00126 velocity_sum_ -= velocities_[velocity_id_]; 00127 velocities_[velocity_id_] = joint_state_->velocity_; 00128 velocity_sum_ += velocities_[velocity_id_]; 00129 velocity_id_ = (velocity_id_ + 1)% velocity_window_; 00130 00131 float average_velocity = velocity_sum_ / velocity_window_; 00132 // vel_pub_.publish(average_velocity); 00133 if (!joint_state_->calibrated_) 00134 return; 00135 00136 if (!initialized_) 00137 starting(); 00138 00139 ros::Time time = robot_->getTime(); 00140 00141 double effort = 0.0; 00142 if (force_control_) { 00143 double vel_effort = velocity_effort(max_velocity_ * sign(force_), time); 00144 if ((fabs(average_velocity) > (0.5 * max_velocity_)) && 00145 (sign(average_velocity) == sign(force_))) { 00146 effort = vel_effort; 00147 if ((fabs(vel_effort) > fabs(force_)) && 00148 (sign(vel_effort) == sign(force_))) { 00149 effort = force_; 00150 } 00151 } else 00152 effort = force_effort(force_); 00153 } else { // position control 00154 double pos_error = position_error(position_); 00155 if (fabs(pos_error) > position_control_limit_) 00156 effort = velocity_effort(max_velocity_ * sign(-pos_error), time); 00157 else 00158 effort = position_effort(position_, time); 00159 } 00160 00161 joint_state_->commanded_effort_ = effort; 00162 00163 last_time_ = time; 00164 } 00165 00166 double JointForceController::force_error(double force) 00167 { 00168 return (joint_state_->commanded_effort_ - force); 00169 } 00170 00171 double JointForceController::force_effort(double force) 00172 { 00173 return force; 00174 } 00175 00176 double JointForceController::position_error(double position) 00177 { 00178 double error(0); 00179 00180 assert(joint_state_->joint_); 00181 00182 if(joint_state_->joint_->type == urdf::Joint::REVOLUTE) 00183 { 00184 angles::shortest_angular_distance_with_limits(position, joint_state_->position_, joint_state_->joint_->limits->lower, joint_state_->joint_->limits->upper,error); 00185 } 00186 else if(joint_state_->joint_->type == urdf::Joint::CONTINUOUS) 00187 { 00188 error = angles::shortest_angular_distance(position, joint_state_->position_); 00189 } 00190 else //prismatic 00191 { 00192 error = joint_state_->position_ - position; 00193 } 00194 00195 return error; 00196 } 00197 00198 double JointForceController::position_effort(double position, ros::Time time) 00199 { 00200 dt_= time - last_time_; 00201 00202 double error = position_error(position); 00203 return position_pid_controller_.updatePid(error, dt_); 00204 } 00205 00206 double JointForceController::velocity_effort(double velocity, ros::Time time) 00207 { 00208 dt_ = time - last_time_; 00209 double error = joint_state_->velocity_ - velocity; 00210 return velocity_pid_controller_.updatePid(error, dt_); 00211 } 00212 00213 void JointForceController::forceCB(const std_msgs::Float64ConstPtr& msg) 00214 { 00215 if (! force_control_) { 00216 position_pid_controller_.reset(); 00217 velocity_pid_controller_.reset(); 00218 reset_velocity_average(); 00219 } 00220 00221 force_ = msg->data; 00222 force_control_ = true; 00223 } 00224 00225 00226 void JointForceController::positionCB(const std_msgs::Float64ConstPtr& msg) 00227 { 00228 if (force_control_) { 00229 position_pid_controller_.reset(); 00230 velocity_pid_controller_.reset(); 00231 } 00232 00233 position_ = msg->data; 00234 force_control_ = false; 00235 } 00236 00237 }