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 }