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 #ifndef YOCS_CONTROLLER_HPP_
00035 #define YOCS_CONTROLLER_HPP_
00036
00037
00038
00039
00040 #include <cmath>
00041 #include <string>
00042 #include <geometry_msgs/Twist.h>
00043 #include <ros/ros.h>
00044 #include <std_msgs/Empty.h>
00045 #include <std_msgs/Float32.h>
00046 #include <tf/transform_listener.h>
00047 #include <yocs_controllers/default_controller.hpp>
00048
00049 namespace yocs
00050 {
00051
00077 class DiffDrivePoseController : public Controller
00078 {
00079 public:
00080 DiffDrivePoseController(ros::NodeHandle& nh, std::string& name) : Controller(),
00081 nh_(nh),
00082 name_(name){};
00083 virtual ~DiffDrivePoseController(){};
00084
00089 bool init();
00090
00094 void spinOnce();
00095
00096 private:
00100 bool getPoseDiff();
00104 void getControlOutput();
00108 void setControlOutput();
00109
00114 void controlMaxVelCB(const std_msgs::Float32ConstPtr msg);
00115
00120 void enableCB(const std_msgs::EmptyConstPtr msg);
00121
00126 void disableCB(const std_msgs::EmptyConstPtr msg);
00127
00128
00129 ros::NodeHandle nh_;
00130 std::string name_;
00131
00132
00134 ros::Subscriber enable_controller_subscriber_;
00136 ros::Subscriber disable_controller_subscriber_;
00138 ros::Subscriber control_velocity_subscriber_;
00140 ros::Publisher command_velocity_publisher_;
00141
00142
00144 double r_;
00146 double theta_;
00148 double delta_;
00150 double v_;
00152 double v_max_;
00154 double w_;
00156 double w_max_;
00158 double cur_;
00160 double k_1_;
00162 double k_2_;
00167 double beta_;
00172 double lambda_;
00173
00175 tf::TransformListener tf_listener_;
00177 tf::StampedTransform tf_goal_pose_rel_;
00179 std::string base_frame_name_;
00181 std::string goal_frame_name_;
00182 };
00183
00184 bool DiffDrivePoseController::init()
00185 {
00186 enable_controller_subscriber_ = nh_.subscribe("enable", 10, &DiffDrivePoseController::enableCB, this);
00187 disable_controller_subscriber_ = nh_.subscribe("disable", 10, &DiffDrivePoseController::disableCB, this);
00188 control_velocity_subscriber_ = nh_.subscribe("control_max_vel", 10, &DiffDrivePoseController::controlMaxVelCB, this);
00189 command_velocity_publisher_ = nh_.advertise<geometry_msgs::Twist>("command_velocity", 10);
00190
00191
00192 base_frame_name_ = "base_footprint";
00193 if(!nh_.getParam("base_frame_name", base_frame_name_))
00194 {
00195 ROS_WARN_STREAM("Couldn't retrieve parameter 'base_frame_name' from parameter server! Using default '"
00196 << base_frame_name_ << "'. [" << name_ <<"]");
00197 }
00198 goal_frame_name_ = "base_goal_pose";
00199 if(!nh_.getParam("goal_frame_name", goal_frame_name_))
00200 {
00201 ROS_WARN_STREAM("Couldn't retrieve parameter 'goal_frame_name' from parameter server! Using default '"
00202 << goal_frame_name_ << "'. [" << name_ <<"]");
00203 }
00204 v_ = 0.0;
00205 v_max_ = 0.5;
00206 if(!nh_.getParam("v_max", v_max_))
00207 {
00208 ROS_WARN_STREAM("Couldn't retrieve parameter 'v_max' from parameter server! Using default '"
00209 << v_max_ << "'. [" << name_ <<"]");
00210 }
00211 w_max_ = M_PI / 4 * v_max_;
00212 k_1_ = 1.0;
00213 if(!nh_.getParam("k_1", k_1_))
00214 {
00215 ROS_WARN_STREAM("Couldn't retrieve parameter 'k_1' from parameter server! Using default '"
00216 << k_1_ << "'. [" << name_ <<"]");
00217 }
00218 k_2_ = 3.0;
00219 if(!nh_.getParam("k_2", k_2_))
00220 {
00221 ROS_WARN_STREAM("Couldn't retrieve parameter 'k_2' from parameter server! Using default '"
00222 << k_2_ << "'. [" << name_ <<"]");
00223 }
00224 beta_ = 0.4;
00225 if(!nh_.getParam("beta", beta_))
00226 {
00227 ROS_WARN_STREAM("Couldn't retrieve parameter 'beta' from parameter server! Using default '"
00228 << beta_ << "'. [" << name_ <<"]");
00229 }
00230 lambda_ = 2.0;
00231 if(!nh_.getParam("lambda", lambda_))
00232 {
00233 ROS_WARN_STREAM("Couldn't retrieve parameter 'lambda' from parameter server! Using default '"
00234 << lambda_ << "'. [" << name_ <<"]");
00235 }
00236 ROS_DEBUG_STREAM("Controller initialised with the following parameters: [" << name_ <<"]");
00237 ROS_DEBUG_STREAM("base_frame_name = " << base_frame_name_ <<", goal_frame_name = "
00238 << goal_frame_name_ << " [" << name_ <<"]");
00239 ROS_DEBUG_STREAM("v_max = " << v_max_ <<", k_1 = " << k_1_ << ", k_2 = " << k_2_
00240 << ", beta = " << beta_ << ", lambda = " << lambda_ << " [" << name_ <<"]");
00241 return true;
00242 };
00243
00244 void DiffDrivePoseController::spinOnce()
00245 {
00246 if (this->getState())
00247 {
00248 ROS_INFO_STREAM_THROTTLE(1.0, "Controller spinning. [" << name_ <<"]");
00249
00250 if (!getPoseDiff())
00251 {
00252 ROS_WARN_STREAM_THROTTLE(1.0, "Getting pose difference failed. Skipping control loop. [" << name_ <<"]");
00253 return;
00254 }
00255
00256 getControlOutput();
00257
00258 setControlOutput();
00259
00260 ROS_DEBUG_STREAM_THROTTLE(1.0, "Current state: [" << name_ <<"]");
00261 ROS_DEBUG_STREAM_THROTTLE(1.0, "r = " << r_ << ", theta = " << theta_ << ", delta = " << delta_
00262 << " [" << name_ <<"]");
00263 ROS_DEBUG_STREAM_THROTTLE(1.0, "cur = " << cur_ << ", v = " << v_ << ", w = " << w_ << " [" << name_ <<"]");
00264 }
00265 else
00266 {
00267 ROS_WARN_STREAM_THROTTLE(3.0, "Controller is disabled. Idling ... [" << name_ <<"]");
00268 }
00269 };
00270
00271 bool DiffDrivePoseController::getPoseDiff()
00272 {
00273
00274 try
00275 {
00276 tf_listener_.lookupTransform(base_frame_name_, goal_frame_name_, ros::Time(0), tf_goal_pose_rel_);
00277 }
00278 catch (tf::TransformException const &ex)
00279 {
00280 ROS_WARN_STREAM_THROTTLE(1.0, "Couldn't get transform from base to goal pose! [" << name_ <<"]");
00281 ROS_DEBUG_STREAM_THROTTLE(1.0, "tf error: " << ex.what());
00282 return false;
00283 }
00284
00285
00286 r_ = std::sqrt(std::pow(tf_goal_pose_rel_.getOrigin().getX(), 2)
00287 + std::pow(tf_goal_pose_rel_.getOrigin().getY(), 2));
00288
00289 delta_ = std::atan2(-tf_goal_pose_rel_.getOrigin().getY(), tf_goal_pose_rel_.getOrigin().getX());
00290
00291
00292 theta_ = tf::getYaw(tf_goal_pose_rel_.getRotation()) + delta_;
00293
00294 return true;
00295 };
00296
00297 void DiffDrivePoseController::getControlOutput()
00298 {
00299 cur_ = (-1 / r_) * (k_2_ * (delta_ - std::atan(-k_1_ * theta_))
00300 + (1 + (k_1_ / (1 + std::pow((k_1_ * theta_), 2)))) * sin(delta_));
00301 v_ = v_max_ / (1 + beta_ * std::pow(std::abs(cur_), lambda_));
00302 w_ = cur_ * v_;
00303 if (w_ > w_max_)
00304 {
00305 w_ = w_max_;
00306 }
00307 };
00308
00309 void DiffDrivePoseController::setControlOutput()
00310 {
00311 geometry_msgs::TwistPtr cmd_vel(new geometry_msgs::Twist());
00312 cmd_vel->linear.x = v_;
00313 cmd_vel->angular.z = w_;
00314 command_velocity_publisher_.publish(cmd_vel);
00315 };
00316
00317 void DiffDrivePoseController::controlMaxVelCB(const std_msgs::Float32ConstPtr msg)
00318 {
00319 v_max_ = msg->data;
00320 ROS_INFO_STREAM("Maximum linear control velocity has been set to " << v_max_ << ". [" << name_ << "]");
00321 };
00322
00323 void DiffDrivePoseController::enableCB(const std_msgs::EmptyConstPtr msg)
00324 {
00325 if (this->enable())
00326 {
00327 ROS_INFO_STREAM("Controller has been enabled. [" << name_ << "]");
00328 }
00329 else
00330 {
00331 ROS_INFO_STREAM("Controller was already enabled. [" << name_ <<"]");
00332 }
00333 };
00334
00335 void DiffDrivePoseController::disableCB(const std_msgs::EmptyConstPtr msg)
00336 {
00337 if (this->disable())
00338 {
00339 ROS_INFO_STREAM("Controller has been disabled. [" << name_ <<"]");
00340 }
00341 else
00342 {
00343 ROS_INFO_STREAM("Controller was already disabled. [" << name_ <<"]");
00344 }
00345 };
00346
00347 }
00348
00349 #endif