gazebo_ros_katana_gripper.cpp
Go to the documentation of this file.
1 /*
2  * UOS-ROS packages - Robot Operating System code by the University of Osnabrück
3  * Copyright (C) 2011 University of Osnabrück
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * gazebo_ros_katana_gripper.cpp
20  *
21  * Created on: 29.08.2011
22  * Author: Martin Günther <mguenthe@uos.de>
23  */
24 
26 #include <sensor_msgs/JointState.h>
27 
28 #include <ros/time.h>
29 
30 using namespace gazebo;
31 
33  publish_counter_(0)
34 {
35  this->spinner_thread_ = new boost::thread(boost::bind(&GazeboRosKatanaGripper::spin, this));
36 
37  for (size_t i = 0; i < NUM_JOINTS; ++i)
38  {
39  joints_[i].reset();
40  }
41 
42 }
43 
45 {
46  // delete all gripper actions
47  for (std::size_t i = 0; i != gripper_action_list_.size(); i++)
48  {
49  /* delete object at pointer */
50  delete gripper_action_list_[i];
51  }
52 
53  rosnode_->shutdown();
54  this->spinner_thread_->join();
55  delete this->spinner_thread_;
56  delete rosnode_;
57 }
58 
59 void GazeboRosKatanaGripper::Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
60 {
61  this->my_world_ = _parent->GetWorld();
62 
63  this->my_parent_ = _parent;
64  if (!this->my_parent_)
65  {
66  ROS_FATAL("Gazebo_ROS_Create controller requires a Model as its parent");
67  return;
68  }
69 
70  this->node_namespace_ = "katana/";
71  if (_sdf->HasElement("robotNamespace"))
72  this->node_namespace_ = _sdf->Get<std::string>("node_namespace") + "/";
73 
74  torque_ = 0.5;
75  if (_sdf->HasElement("max_torque"))
76  torque_ = _sdf->Get<float>("max_torque");
77 
78  joint_names_.resize(NUM_JOINTS);
79  joint_names_[0] = "katana_r_finger_joint";
80  if (_sdf->HasElement("r_finger_joint"))
81  joint_names_[0] = _sdf->Get<std::string>("r_finger_joint");
82 
83  joint_names_[1] = "katana_r_finger_joint";
84  if (_sdf->HasElement("l_finger_joint"))
85  joint_names_[1] = _sdf->Get<std::string>("l_finger_joint");
86 
87  if (!ros::isInitialized())
88  {
89  int argc = 0;
90  char** argv = NULL;
91  ros::init(argc, argv, "gazebo_ros_katana_gripper",
93  }
94 
96 
97  controller_state_pub_ = rosnode_->advertise<katana_msgs::GripperControllerState>("gripper_controller_state", 1);
98 
99  for (size_t i = 0; i < NUM_JOINTS; ++i)
100  {
101  joints_[i] = my_parent_->GetJoint(joint_names_[i]);
102  if (!joints_[i])
103  gzthrow("The controller couldn't get joint " << joint_names_[i]);
104  }
105 
106  // construct pid controller
107  if (!pid_controller_.init(ros::NodeHandle(*rosnode_, "gripper_pid")))
108  {
109  ROS_FATAL("gazebo_ros_katana_gripper could not construct PID controller!");
110  }
111 
112  // create gripper actions
113  katana_gazebo_plugins::IGazeboRosKatanaGripperAction* gripper_grasp_controller_ =
117 
118  // "register" gripper actions
119  gripper_action_list_.push_back(gripper_grasp_controller_);
120  gripper_action_list_.push_back(gripper_jt_controller_);
121 
122  // set default action
123  active_gripper_action_ = gripper_grasp_controller_;
124  updateGains();
125 
126  // Get the name of the parent model
127  std::string modelName = _sdf->GetParent()->Get<std::string>("name");
128 
129  // Listen to the update event. This event is broadcast every
130  // simulation iteration.
131  this->updateConnection = event::Events::ConnectWorldUpdateBegin(
132  boost::bind(&GazeboRosKatanaGripper::UpdateChild, this));
133  gzdbg << "plugin model name: " << modelName << "\n";
134 
135  ROS_INFO("gazebo_ros_katana_gripper plugin initialized");
136 }
137 
139 {
141  #if GAZEBO_MAJOR_VERSION >= 8
142  prev_update_time_ = this->my_world_->SimTime();
143  #else
144  prev_update_time_ = this->my_world_->GetSimTime();
145  #endif
146 }
147 
149 {
150  rosnode_->shutdown();
151 }
152 
154 {
155  // --------------- command joints ---------------
156  #if GAZEBO_MAJOR_VERSION >= 8
157  common::Time time_now = this->my_world_->SimTime();
158  #else
159  common::Time time_now = this->my_world_->GetSimTime();
160  #endif
161  common::Time step_time = time_now - prev_update_time_;
162  prev_update_time_ = time_now;
163  ros::Duration dt = ros::Duration(step_time.Double());
164 
165  double desired_pos[NUM_JOINTS];
166  double actual_pos[NUM_JOINTS];
167  double commanded_effort[NUM_JOINTS];
168 
169  // check for new goals, this my change the active_gripper_action_
171 
172  for (size_t i = 0; i < NUM_JOINTS; ++i)
173  {
174  // desired_pos = 0.3 * sin(0.25 * this->my_world_->GetSimTime());
175  //if ((prev_update_time_.sec / 6) % 2 == 0)
176  // desired_pos[i] = 0.3;
177  //else
178  // desired_pos[i] = -0.44;
179 
181  #if GAZEBO_MAJOR_VERSION >= 8
182  actual_pos[i] = joints_[i]->Position(0);
183  #else
184  actual_pos[i] = joints_[i]->GetAngle(0).Radian();
185  #endif
186  commanded_effort[i] = pid_controller_.computeCommand(desired_pos[i] - actual_pos[i], -joints_[i]->GetVelocity(0), dt);
187 
188  if (commanded_effort[i] > torque_)
189  commanded_effort[i] = torque_;
190  else if (commanded_effort[i] < -torque_)
191  commanded_effort[i] = -torque_;
192 
193  joints_[i]->SetForce(0, commanded_effort[i]);
194 
195  // TODO: ensure that both joints are always having (approximately)
196  // the same joint position, even if one is blocked by an object
197  }
198  if (fabs(commanded_effort[0]) > 0.001)
199  ROS_DEBUG("efforts: r %f, l %f (max: %f)", commanded_effort[0], commanded_effort[1], torque_);
200 
201  // --------------- update gripper_grasp_controller ---------------
202  for (size_t i = 0; i < NUM_JOINTS; ++i)
203  {
204 
205  // update all actions
206  for (std::size_t i = 0; i != gripper_action_list_.size(); i++)
207  {
208  #if GAZEBO_MAJOR_VERSION >= 8
209  gripper_action_list_[i]->setCurrentPoint(joints_[i]->Position(0), joints_[i]->GetVelocity(0));
210  #else
211  gripper_action_list_[i]->setCurrentPoint(joints_[i]->GetAngle(0).Radian(), joints_[i]->GetVelocity(0));
212  #endif
213  }
214 
215  }
216 
217  // --------------- limit publishing frequency to 25 Hz ---------------
218  publish_counter_ = ((publish_counter_ + 1) % 40);
219 
220  if (publish_counter_ == 0)
221  {
222  // --------------- publish gripper controller state ---------------
223  katana_msgs::GripperControllerState controller_state;
224  controller_state.header.stamp = ros::Time::now();
225  for (size_t i = 0; i < NUM_JOINTS; ++i)
226  {
227  controller_state.name.push_back(joints_[i]->GetName());
228  controller_state.actual.push_back(actual_pos[i]);
229  controller_state.desired.push_back(desired_pos[i]);
230  controller_state.error.push_back(desired_pos[i] - actual_pos[i]);
231  }
232 
233  controller_state_pub_.publish(controller_state);
234 
235  // don't publish joint states: The pr2_controller_manager publishes joint states for
236  // ALL joints, not just the ones it controls.
237  //
238  // // --------------- publish joint states ---------------
239  // js_.header.stamp = ros::Time::now();
240  //
241  // for (size_t i = 0; i < NUM_JOINTS; ++i)
242  // {
243  // js_.position[i] = joints_[i]->GetAngle(0).Radian();
244  // js_.velocity[i] = joints_[i]->GetVelocity(0);
245  // js_.effort[i] = commanded_effort[i];
246  //
247  // ROS_DEBUG("publishing gripper joint state %d (effort: %f)", i, commanded_effort[i]);
248  // }
249  //
250  // joint_state_pub_.publish(js_);
251  }
252 }
253 
258 {
259  //TODO: improve the selection of the action, maybe prefer newer started actions (but how to know?)
260  // atm the list gives some kind of priority, and it its impossible to cancel a goal
261  // by submitting a new one to another action (but you can cancel the goal via a message)
262 
263  // search for a new action if the current (or default on) is finished with its goal
264  // if we cant find a new action, just use the current one
266  {
267 
268  // find a new action with a goal
269  for (std::size_t i = 0; i != gripper_action_list_.size(); i++)
270  {
271  // just use the first found
272  if (gripper_action_list_[i]->hasActiveGoal())
273  {
274  // change the active gripper action
276  updateGains();
277 
278  break;
279  }
280  }
281  }
282 }
283 
285 {
286  // PID Controller parameters (gains)
287  double p, i, d, i_max, i_min;
288  // get current values
289  pid_controller_.getGains(p, i, d, i_max, i_min);
290  // overwrite with defaults from the active action
291  active_gripper_action_->getGains(p, i, d, i_max, i_min);
292  // set changed values
293  pid_controller_.setGains(p, i, d, i_max, i_min);
294 }
295 
297 {
298  while (ros::ok())
299  ros::spinOnce();
300 }
301 
d
#define ROS_FATAL(...)
void publish(const boost::shared_ptr< M > &message) const
katana_gazebo_plugins::IGazeboRosKatanaGripperAction * active_gripper_action_
void getGains(double &p, double &i, double &d, double &i_max, double &i_min)
void setGains(double p, double i, double d, double i_max, double i_min, bool antiwindup=false)
ROSCPP_DECL bool isInitialized()
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
virtual void Load(physics::ModelPtr _parent, sdf::ElementPtr _sdf)
GZ_REGISTER_MODEL_PLUGIN(GazeboRosKatanaGripper)
virtual void getGains(double &p, double &i, double &d, double &i_max, double &i_min)=0
bool init(const ros::NodeHandle &n, const bool quiet=false)
std::vector< std::string > joint_names_
double computeCommand(double error, ros::Duration dt)
#define ROS_INFO(...)
ROSCPP_DECL bool ok()
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
virtual GRKAPoint getNextDesiredPoint(ros::Time time)=0
std::vector< katana_gazebo_plugins::IGazeboRosKatanaGripperAction * > gripper_action_list_
static Time now()
physics::JointPtr joints_[NUM_JOINTS]
ROSCPP_DECL void spinOnce()
float torque_
Torque applied to the joints.
#define ROS_DEBUG(...)


katana_gazebo_plugins
Author(s): Martin Günther
autogenerated on Fri Jan 3 2020 04:01:10