$search
00001 /* 00002 * UOS-ROS packages - Robot Operating System code by the University of Osnabrück 00003 * Copyright (C) 2011 University of Osnabrück 00004 * 00005 * This program is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU General Public License 00007 * as published by the Free Software Foundation; either version 2 00008 * of the License, or (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 * 00019 * gazebo_ros_katana_gripper.cpp 00020 * 00021 * Created on: 29.08.2011 00022 * Author: Martin Günther <mguenthe@uos.de> 00023 */ 00024 00025 #include <katana_gazebo_plugins/gazebo_ros_katana_gripper.h> 00026 #include <sensor_msgs/JointState.h> 00027 00028 #include <gazebo/Joint.hh> 00029 //#include <gazebo/Body.hh> 00030 //#include <gazebo/Geom.hh> 00031 #include <gazebo/Simulator.hh> 00032 //#include <gazebo/Entity.hh> 00033 #include <gazebo/GazeboError.hh> 00034 #include <gazebo/ControllerFactory.hh> 00035 //#include <gazebo/XMLConfig.hh> 00036 00037 #include <ros/time.h> 00038 00039 using namespace gazebo; 00040 00041 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_katana_gripper", GazeboRosKatanaGripper) 00042 00043 GazeboRosKatanaGripper::GazeboRosKatanaGripper(Entity *parent) : 00044 Controller(parent), publish_counter_(0) 00045 { 00046 ros::MultiThreadedSpinner s(1); 00047 boost::thread spinner_thread(boost::bind(&ros::spin, s)); 00048 00049 my_parent_ = dynamic_cast<Model*>(parent); 00050 00051 if (!my_parent_) 00052 gzthrow("Gazebo_ROS_Katana_Gripper controller requires a Model as its parent"); 00053 00054 Param::Begin(&this->parameters); 00055 node_namespaceP_ = new ParamT<std::string>("node_namespace", "katana", 0); 00056 joint_nameP_.push_back(new ParamT<std::string>("r_finger_joint", "katana_r_finger_joint", 1)); 00057 joint_nameP_.push_back(new ParamT<std::string>("l_finger_joint", "katana_l_finger_joint", 1)); 00058 torqueP_ = new ParamT<float>("max_torque", 0.5, 1); 00059 Param::End(); 00060 00061 for (size_t i = 0; i < NUM_JOINTS; ++i) 00062 { 00063 joints_[i] = NULL; 00064 } 00065 00066 } 00067 00068 GazeboRosKatanaGripper::~GazeboRosKatanaGripper() 00069 { 00070 delete torqueP_; 00071 delete node_namespaceP_; 00072 for (size_t i = 0; i < NUM_JOINTS; ++i) 00073 { 00074 delete joint_nameP_[i]; 00075 } 00076 delete rosnode_; 00077 00078 // delete all gripper actions 00079 for (std::size_t i = 0; i != gripper_action_list_.size(); i++) 00080 { 00081 /* delete object at pointer */ 00082 delete gripper_action_list_[i]; 00083 } 00084 00085 } 00086 00087 void GazeboRosKatanaGripper::LoadChild(XMLConfigNode *node) 00088 { 00089 node_namespaceP_->Load(node); 00090 torqueP_->Load(node); 00091 for (size_t i = 0; i < NUM_JOINTS; ++i) 00092 { 00093 joint_nameP_[i]->Load(node); 00094 joints_[i] = my_parent_->GetJoint(**joint_nameP_[i]); 00095 if (!joints_[i]) 00096 gzthrow("The controller couldn't get a joint"); 00097 } 00098 00099 if (!ros::isInitialized()) 00100 { 00101 int argc = 0; 00102 char** argv = NULL; 00103 ros::init(argc, argv, "gazebo_ros_katana_gripper", 00104 ros::init_options::NoSigintHandler | ros::init_options::AnonymousName); 00105 } 00106 00107 rosnode_ = new ros::NodeHandle(**node_namespaceP_); 00108 00109 // joint_state_pub_ = rosnode_->advertise<sensor_msgs::JointState> ("/joint_states", 1); 00110 controller_state_pub_ = rosnode_->advertise<katana_msgs::GripperControllerState>("gripper_controller_state", 1); 00111 00112 // for (size_t i = 0; i < NUM_JOINTS; ++i) 00113 // { 00114 // js_.name.push_back(**joint_nameP_[i]); 00115 // js_.position.push_back(0); 00116 // js_.velocity.push_back(0); 00117 // js_.effort.push_back(0); 00118 // } 00119 00120 // construct pid controller 00121 if (!pid_controller_.init(ros::NodeHandle(*rosnode_, "gripper_pid"))) 00122 { 00123 ROS_FATAL("gazebo_ros_katana_gripper could not construct PID controller!"); 00124 } 00125 00126 // create gripper actions 00127 katana_gazebo_plugins::IGazeboRosKatanaGripperAction* gripper_grasp_controller_ = 00128 new katana_gazebo_plugins::KatanaGripperGraspController(ros::NodeHandle(**node_namespaceP_)); 00129 katana_gazebo_plugins::IGazeboRosKatanaGripperAction* gripper_jt_controller_ = 00130 new katana_gazebo_plugins::KatanaGripperJointTrajectoryController(ros::NodeHandle(**node_namespaceP_)); 00131 00132 // "register" gripper actions 00133 gripper_action_list_.push_back(gripper_grasp_controller_); 00134 gripper_action_list_.push_back(gripper_jt_controller_); 00135 00136 // set default action 00137 active_gripper_action_ = gripper_grasp_controller_; 00138 //active_gripper_action_ = gripper_jt_controller_; 00139 } 00140 00141 void GazeboRosKatanaGripper::InitChild() 00142 { 00143 pid_controller_.reset(); 00144 prev_update_time_ = Simulator::Instance()->GetSimTime(); 00145 } 00146 00147 void GazeboRosKatanaGripper::FiniChild() 00148 { 00149 rosnode_->shutdown(); 00150 } 00151 00152 void GazeboRosKatanaGripper::UpdateChild() 00153 { 00154 // --------------- command joints --------------- 00155 Time step_time = Simulator::Instance()->GetSimTime() - prev_update_time_; 00156 prev_update_time_ = Simulator::Instance()->GetSimTime(); 00157 ros::Duration dt = ros::Duration(step_time.Double()); 00158 00159 double desired_pos[NUM_JOINTS]; 00160 double actual_pos[NUM_JOINTS]; 00161 double commanded_effort[NUM_JOINTS]; 00162 00163 // check for new goals, this my change the active_gripper_action_ 00164 this->updateActiveGripperAction(); 00165 00166 // PID Controller paramters (gains) 00167 00168 double p, i, d, i_max, i_min; 00169 // get current values 00170 pid_controller_.getGains(p, i, d, i_max, i_min); 00171 // change values by the active action 00172 active_gripper_action_->getGains(p, i, d, i_max, i_min); 00173 // set changed values 00174 pid_controller_.setGains(p, i, d, i_max, i_min); 00175 00176 for (size_t i = 0; i < NUM_JOINTS; ++i) 00177 { 00178 // desired_pos = 0.3 * sin(0.25 * Simulator::Instance()->GetSimTime()); 00179 //if ((prev_update_time_.sec / 6) % 2 == 0) 00180 // desired_pos[i] = 0.3; 00181 //else 00182 // desired_pos[i] = -0.44; 00183 00184 desired_pos[i] = active_gripper_action_->getNextDesiredPoint(ros::Time::now()).position; 00185 actual_pos[i] = joints_[i]->GetAngle(0).GetAsRadian(); 00186 00187 commanded_effort[i] = pid_controller_.updatePid(actual_pos[i] - desired_pos[i], joints_[i]->GetVelocity(0), dt); 00188 00189 joints_[i]->SetForce(0, commanded_effort[i]); 00190 00191 // I set this every time just in case some other entity changed it 00192 joints_[i]->SetMaxForce(0, **(torqueP_)); 00193 00194 // TODO: ensure that both joints are always having (approximately) 00195 // the same joint position, even if one is blocked by an object 00196 } 00197 00198 // --------------- update gripper_grasp_controller --------------- 00199 for (size_t i = 0; i < NUM_JOINTS; ++i) 00200 { 00201 00202 // update all actions 00203 for (std::size_t i = 0; i != gripper_action_list_.size(); i++) 00204 { 00205 gripper_action_list_[i]->setCurrentPoint(joints_[i]->GetAngle(0).GetAsRadian(), joints_[i]->GetVelocity(0)); 00206 } 00207 00208 } 00209 00210 // --------------- limit publishing frequency to 25 Hz --------------- 00211 publish_counter_ = ((publish_counter_ + 1) % 40); 00212 00213 if (publish_counter_ == 0) 00214 { 00215 // --------------- publish gripper controller state --------------- 00216 katana_msgs::GripperControllerState controller_state; 00217 controller_state.header.stamp = ros::Time::now(); 00218 for (size_t i = 0; i < NUM_JOINTS; ++i) 00219 { 00220 controller_state.name.push_back(joints_[i]->GetName()); 00221 controller_state.actual.push_back(actual_pos[i]); 00222 controller_state.desired.push_back(desired_pos[i]); 00223 controller_state.error.push_back(desired_pos[i] - actual_pos[i]); 00224 } 00225 00226 controller_state_pub_.publish(controller_state); 00227 00228 // don't publish joint states: The pr2_controller_manager publishes joint states for 00229 // ALL joints, not just the ones it controls. 00230 // 00231 // // --------------- publish joint states --------------- 00232 // js_.header.stamp = ros::Time::now(); 00233 // 00234 // for (size_t i = 0; i < NUM_JOINTS; ++i) 00235 // { 00236 // js_.position[i] = joints_[i]->GetAngle(0).GetAsRadian(); 00237 // js_.velocity[i] = joints_[i]->GetVelocity(0); 00238 // js_.effort[i] = commanded_effort[i]; 00239 // 00240 // ROS_DEBUG("publishing gripper joint state %d (effort: %f)", i, commanded_effort[i]); 00241 // } 00242 // 00243 // joint_state_pub_.publish(js_); 00244 } 00245 } 00246 00250 void GazeboRosKatanaGripper::updateActiveGripperAction() 00251 { 00252 //TODO: improve the selection of the action, maybe prefer newer started actions (but how to know?) 00253 // atm the list gives some kind of priority, and it its impossible to cancel a goal 00254 // by submitting a new one to another action (but you can cancel the goal via a message) 00255 00256 // search for a new action if the current (or default on) is finished with its goal 00257 // if we cant find a new action, just use the current one 00258 if (!active_gripper_action_->hasActiveGoal()) 00259 { 00260 00261 // find a new action with a goal 00262 for (std::size_t i = 0; i != gripper_action_list_.size(); i++) 00263 { 00264 // just use the first found 00265 if (gripper_action_list_[i]->hasActiveGoal()) 00266 { 00267 // change the active gripper action 00268 active_gripper_action_ = gripper_action_list_[i]; 00269 break; 00270 } 00271 } 00272 00273 } 00274 00275 } 00276