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 #include "ias_mechanism_controllers/multi_joint_velocity_controller.h"
00035 #include <sstream>
00036 #include "angles/angles.h"
00037 #include "pluginlib/class_list_macros.h"
00038 
00039 PLUGINLIB_DECLARE_CLASS(ias_mechanism_controllers, MultiJointVelocityController, controller::MultiJointVelocityController, pr2_controller_interface::Controller)
00040 
00041 namespace controller {
00042 
00043 
00044 MultiJointVelocityController::MultiJointVelocityController()
00045   : loop_count_(0), robot_(NULL)
00046 {
00047 }
00048 
00049 MultiJointVelocityController::~MultiJointVelocityController()
00050 {
00051   sub_command_.shutdown();
00052 }
00053 
00054 bool MultiJointVelocityController::init(pr2_mechanism_model::RobotState *robot, ros::NodeHandle &n)
00055 {
00056   using namespace XmlRpc;
00057   node_ = n;
00058   robot_ = robot;
00059 
00060   
00061   XmlRpc::XmlRpcValue joint_names;
00062   if (!node_.getParam("joints", joint_names))
00063   {
00064     ROS_ERROR("No joints given. (namespace: %s)", node_.getNamespace().c_str());
00065     return false;
00066   }
00067   if (joint_names.getType() != XmlRpc::XmlRpcValue::TypeArray)
00068   {
00069     ROS_ERROR("Malformed joint specification.  (namespace: %s)", node_.getNamespace().c_str());
00070     return false;
00071   }
00072   for (int i = 0; i < joint_names.size(); ++i)
00073   {
00074     XmlRpcValue &name_value = joint_names[i];
00075     if (name_value.getType() != XmlRpcValue::TypeString)
00076     {
00077       ROS_ERROR("Array of joint names should contain all strings.  (namespace: %s)",
00078                 node_.getNamespace().c_str());
00079       return false;
00080     }
00081 
00082     pr2_mechanism_model::JointState *j = robot->getJointState((std::string)name_value);
00083     if (!j) {
00084       ROS_ERROR("Joint not found: %s. (namespace: %s)",
00085                 ((std::string)name_value).c_str(), node_.getNamespace().c_str());
00086       return false;
00087     }
00088     joints_.push_back(j);
00089   }
00090 
00091   
00092   for (size_t i = 0; i < joints_.size(); ++i)
00093   {
00094     if (!joints_[i]->calibrated_)
00095     {
00096       ROS_ERROR("Joint %s was not calibrated (namespace: %s)",
00097                 joints_[i]->joint_->name.c_str(), node_.getNamespace().c_str());
00098       return false;
00099     }
00100   }
00101 
00102   
00103   std::string gains_ns;
00104   if (!node_.getParam("gains", gains_ns))
00105     gains_ns = node_.getNamespace() + "/gains";
00106   pids_.resize(joints_.size());
00107   for (size_t i = 0; i < joints_.size(); ++i)
00108     if (!pids_[i].init(ros::NodeHandle(gains_ns + "/" + joints_[i]->joint_->name)))
00109       return false;
00110 
00111 
00112   output_filters_.resize(joints_.size());
00113   for (size_t i = 0; i < joints_.size(); ++i)
00114   {
00115     std::string p = "output_filters/" + joints_[i]->joint_->name;
00116     if (node_.hasParam(p))
00117     {
00118       output_filters_[i].reset(new filters::FilterChain<double>("double"));
00119       if (!output_filters_[i]->configure(node_.resolveName(p)))
00120         output_filters_[i].reset();
00121     }
00122   }
00123 
00124   sub_command_ = node_.subscribe("command", 1, &MultiJointVelocityController::commandCB, this);
00125 
00126   command_.resize(joints_.size());
00127 
00128   controller_state_publisher_.reset(
00129     new realtime_tools::RealtimePublisher<pr2_controllers_msgs::JointTrajectoryControllerState>
00130     (node_, "state", 1));
00131   controller_state_publisher_->lock();
00132   for (size_t j = 0; j < joints_.size(); ++j)
00133     controller_state_publisher_->msg_.joint_names.push_back(joints_[j]->joint_->name);
00134   controller_state_publisher_->msg_.desired.velocities.resize(joints_.size());
00135   controller_state_publisher_->msg_.actual.positions.resize(joints_.size());
00136   controller_state_publisher_->msg_.actual.velocities.resize(joints_.size());
00137   controller_state_publisher_->msg_.error.velocities.resize(joints_.size());
00138   controller_state_publisher_->unlock();
00139 
00140 
00141   return true;
00142 }
00143 
00144 void MultiJointVelocityController::starting()
00145 {
00146   last_time_ = robot_->getTime();
00147 
00148   for (size_t i = 0; i < pids_.size(); ++i)
00149     pids_[i].reset();
00150 
00151   
00152 }
00153 
00154 void MultiJointVelocityController::update()
00155 {
00156   ros::Time time = robot_->getTime();
00157   ros::Duration dt = time - last_time_;
00158   last_time_ = time;
00159 
00160   double command[joints_.size()];
00161 
00162   boost::mutex::scoped_lock guard(command_mutex_);
00163   for(unsigned int i=0; i < command_.size(); ++i)
00164     command[i] = command_[i];
00165   guard.unlock();
00166 
00167   double error[joints_.size()];
00168   for (size_t i = 0; i < joints_.size(); ++i)
00169   {
00170     error[i] = joints_[i]->velocity_ - command[i];
00171     double effort = pids_[i].updatePid(error[i], dt);
00172     double effort_filtered = effort;
00173     if (output_filters_[i])
00174       output_filters_[i]->update(effort, effort_filtered);
00175     joints_[i]->commanded_effort_ += effort_filtered;
00176   }
00177 
00178 
00179   
00180 
00181   if (loop_count_ % 10 == 0)
00182   {
00183     if (controller_state_publisher_ && controller_state_publisher_->trylock())
00184     {
00185       controller_state_publisher_->msg_.header.stamp = time;
00186       for (size_t j = 0; j < joints_.size(); ++j)
00187       {
00188         controller_state_publisher_->msg_.desired.velocities[j] = command[j];
00189         controller_state_publisher_->msg_.actual.positions[j] = joints_[j]->position_;
00190         controller_state_publisher_->msg_.actual.velocities[j] = joints_[j]->velocity_;
00191         controller_state_publisher_->msg_.error.velocities[j] = error[j];
00192       }
00193       controller_state_publisher_->unlockAndPublish();
00194     }
00195   }
00196 
00197   ++loop_count_;
00198 }
00199 
00200 void MultiJointVelocityController::commandCB(const std_msgs::Float64MultiArray::ConstPtr &msg)
00201 {
00202   boost::mutex::scoped_lock guard(command_mutex_);
00203   for(unsigned int i=0; i < command_.size(); ++i)
00204     command_[i] = msg->data[i];
00205 }
00206 
00207 
00208 
00209 
00210 }