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 #ifndef FETCH_GAZEBO_JOINT_HANDLE_H
00039 #define FETCH_GAZEBO_JOINT_HANDLE_H
00040
00041 #include <ros/ros.h>
00042 #include <angles/angles.h>
00043 #include <control_toolbox/pid.h>
00044 #include <gazebo/physics/physics.hh>
00045 #include <robot_controllers_interface/joint_handle.h>
00046 #include <robot_controllers_interface/controller_manager.h>
00047
00048 namespace gazebo
00049 {
00050
00051 class JointHandle : public robot_controllers::JointHandle
00052 {
00053 enum CommandState
00054 {
00055 MODE_DISABLED,
00056 MODE_CONTROL_EFFORT,
00057 MODE_CONTROL_VELOCITY,
00058 MODE_CONTROL_POSITION
00059 };
00060
00061 public:
00062 JointHandle(physics::JointPtr& joint,
00063 const double velocity_limit,
00064 const double effort_limit,
00065 const bool continuous) :
00066 joint_(joint),
00067 actual_velocity_(0.0),
00068 mode_(MODE_DISABLED)
00069 {
00070 ros::NodeHandle nh("~");
00071
00072
00073 position_pid_.init(ros::NodeHandle(nh, getName() + "/position"));
00074 velocity_pid_.init(ros::NodeHandle(nh, getName() + "/velocity"));
00075
00076
00077 velocity_limit_ = velocity_limit;
00078 effort_limit_ = effort_limit;
00079 continuous_ = continuous;
00080 }
00081 virtual ~JointHandle()
00082 {
00083 }
00084
00091 virtual void setPosition(double position, double velocity, double effort)
00092 {
00093
00094
00095 desired_position_ += position;
00096 desired_velocity_ += velocity;
00097 desired_effort_ += effort;
00098 mode_ = MODE_CONTROL_POSITION;
00099 }
00100
00106 virtual void setVelocity(double velocity, double effort)
00107 {
00108 desired_velocity_ += velocity;
00109 desired_effort_ += effort;
00110 if (mode_ != MODE_CONTROL_POSITION)
00111 mode_ = MODE_CONTROL_VELOCITY;
00112 }
00113
00118 virtual void setEffort(double effort)
00119 {
00120 desired_effort_ += effort;
00121 if (mode_ != MODE_CONTROL_POSITION &&
00122 mode_ != MODE_CONTROL_VELOCITY)
00123 mode_ = MODE_CONTROL_EFFORT;
00124 }
00125
00127 virtual double getPosition()
00128 {
00129 if (continuous_)
00130 {
00131 return angles::normalize_angle(joint_->GetAngle(0).Radian());
00132 }
00133 return joint_->GetAngle(0).Radian();
00134 }
00135
00137 virtual double getVelocity()
00138 {
00139 return actual_velocity_;
00140 }
00141
00143 virtual double getEffort()
00144 {
00145 return applied_effort_;
00146 }
00147
00148
00149 virtual bool isContinuous()
00150 {
00151 return continuous_;
00152 }
00153
00155 virtual double getPositionMin()
00156 {
00157 return joint_->GetLowerLimit(0).Radian();
00158 }
00159
00161 virtual double getPositionMax()
00162 {
00163 return joint_->GetUpperLimit(0).Radian();
00164 }
00165
00167 virtual double getVelocityMax()
00168 {
00169 if (velocity_limit_ < 0.0)
00170 return joint_->GetVelocityLimit(0);
00171 else
00172 return velocity_limit_;
00173 }
00174
00176 virtual double getEffortMax()
00177 {
00178
00179
00180
00181
00182
00183
00184
00185
00186 if (effort_limit_ < 0.0)
00187 return joint_->GetEffortLimit(0);
00188 else
00189 return effort_limit_;
00190 }
00191
00193 virtual std::string getName()
00194 {
00195 return joint_->GetName();
00196 }
00197
00199 virtual void reset()
00200 {
00201 desired_position_ = 0.0;
00202 desired_velocity_ = 0.0;
00203 desired_effort_ = 0.0;
00204 mode_ = MODE_DISABLED;
00205 }
00206
00208 void update(const ros::Time now, const ros::Duration dt)
00209 {
00210 actual_velocity_ += 0.1 * (joint_->GetVelocity(0) - actual_velocity_);
00211
00212 double effort = 0.0;
00213 if (mode_ == MODE_CONTROL_POSITION)
00214 {
00215 double p_error = angles::shortest_angular_distance(getPosition(), desired_position_);
00216 double v = position_pid_.computeCommand(p_error, dt) + desired_velocity_;
00217 v = std::min(getVelocityMax(), std::max(-getVelocityMax(), v));
00218 double t = velocity_pid_.computeCommand(v - actual_velocity_, dt);
00219 effort = t + desired_effort_;
00220 }
00221 else if (mode_ == MODE_CONTROL_VELOCITY)
00222 {
00223 double t = velocity_pid_.computeCommand(desired_velocity_ - actual_velocity_, dt);
00224 effort = t + desired_effort_;
00225 }
00226 else if (mode_ == MODE_CONTROL_EFFORT)
00227 {
00228 effort = desired_effort_;
00229 }
00230
00231
00232 double lim = getEffortMax();
00233 applied_effort_ = std::max(-lim, std::min(effort, lim));
00234
00235
00236 joint_->SetForce(0, applied_effort_);
00237 }
00238
00239 private:
00240 physics::JointPtr joint_;
00241
00242 double desired_position_;
00243 double desired_velocity_;
00244 double desired_effort_;
00245
00247 int mode_;
00248
00249 control_toolbox::Pid position_pid_;
00250 control_toolbox::Pid velocity_pid_;
00251
00253 double velocity_limit_;
00254
00256 double effort_limit_;
00257
00258
00259 bool continuous_;
00260
00262 double applied_effort_;
00263 double actual_velocity_;
00264
00265
00266 JointHandle(const JointHandle&);
00267 JointHandle& operator=(const JointHandle&);
00268 };
00269
00270 typedef boost::shared_ptr<JointHandle> JointHandlePtr;
00271
00272 }
00273
00274 #endif // FETCH_GAZEBO_JOINT_HANDLE_H