arm_sim_controller.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2012, Àngel Santamaria-Navarro, IRI-UPC-CSIC
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Mobile Robotics group,
00013 //       Institut de robòtica i infomàtica industrial (IRI), 
00014 //       nor the names of its contributors may be used to
00015 //       endorse or promote products derived from this software without
00016 //       specific prior written permission.
00017 //
00018 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00019 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00020 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00021 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00022 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00023 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00024 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00025 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00026 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00027 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 //=================================================================================================
00029 
00030 #include "arm_sim_controller/arm_sim_controller.h"
00031 #include "common/Events.hh"
00032 #include "physics/physics.h"
00033 
00034 namespace gazebo {
00035 
00037 SimpleArmPlugin::SimpleArmPlugin()
00038 {
00039 }
00040 SimpleArmPlugin::~SimpleArmPlugin()
00041 {
00042   event::Events::DisconnectWorldUpdateStart(updateConnection_);
00043 
00044   node_handle_->shutdown();
00045   delete node_handle_;
00046 }
00048 // Load the controller
00049 void SimpleArmPlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf)
00050 {
00051   this->model_ = _model;
00052  
00053   // load parameters
00054   if (!_sdf->HasElement("robotNamespace"))
00055     namespace_.clear();
00056   else
00057     namespace_ = _sdf->GetElement("robotNamespace")->GetValueString();
00058 
00059   if (!_sdf->HasElement("topicName"))
00060     joints_topic_ = "joints_state";
00061   else
00062     joints_topic_ = _sdf->GetElement("topicName")->GetValueString();
00063     
00064   if (!_sdf->HasElement("joint1"))
00065   { //gzerr << "SimpleArm plugin missing <joint1> element\n";
00066     ROS_FATAL("SimpleArm plugin missing <joint1> element\n");
00067     return;
00068   }
00069   // get all joints
00070   this->joints_[0] = _model->GetJoint(_sdf->GetElement("joint1")->GetValueString());
00071 
00072   this->jointPIDs_[0] = common::PID(
00073     _sdf->GetElement("joint1_pid")->GetValueVector3().x,
00074     _sdf->GetElement("joint1_pid")->GetValueVector3().y,
00075     _sdf->GetElement("joint1_pid")->GetValueVector3().z,
00076     _sdf->GetElement("joint1_ilim")->GetValueVector2d().x,
00077     _sdf->GetElement("joint1_ilim")->GetValueVector2d().y, 
00078     _sdf->GetElement("joint1_cmdlim")->GetValueVector2d().x,
00079     _sdf->GetElement("joint1_cmdlim")->GetValueVector2d().y);
00080   if (!_sdf->HasElement("joint2"))
00081   { //gzerr << "SimpleArm plugin missing <joint2> element\n";
00082     ROS_FATAL("SimpleArm plugin missing <joint2> element\n");
00083     return;
00084   }
00085   this->joints_[1] = _model->GetJoint(_sdf->GetElement("joint2")->GetValueString());
00086   this->jointPIDs_[1] = common::PID(
00087     _sdf->GetElement("joint2_pid")->GetValueVector3().x,
00088     _sdf->GetElement("joint2_pid")->GetValueVector3().y,
00089     _sdf->GetElement("joint2_pid")->GetValueVector3().z,
00090     _sdf->GetElement("joint2_ilim")->GetValueVector2d().x,
00091     _sdf->GetElement("joint2_ilim")->GetValueVector2d().y,    
00092     _sdf->GetElement("joint2_cmdlim")->GetValueVector2d().x,
00093     _sdf->GetElement("joint2_cmdlim")->GetValueVector2d().y);
00094 
00095   if (!_sdf->HasElement("joint3"))
00096   { //gzerr << "SimpleArm plugin missing <joint3> element\n";
00097     ROS_FATAL("SimpleArm plugin missing <joint3> element\n");
00098     return;
00099   }
00100   this->joints_[2] = _model->GetJoint(_sdf->GetElement("joint3")->GetValueString());
00101   this->jointPIDs_[2] = common::PID(
00102     _sdf->GetElement("joint3_pid")->GetValueVector3().x,
00103     _sdf->GetElement("joint3_pid")->GetValueVector3().y,
00104     _sdf->GetElement("joint3_pid")->GetValueVector3().z,
00105     _sdf->GetElement("joint3_ilim")->GetValueVector2d().x,
00106     _sdf->GetElement("joint3_ilim")->GetValueVector2d().y,
00107     _sdf->GetElement("joint3_cmdlim")->GetValueVector2d().x,
00108     _sdf->GetElement("joint3_cmdlim")->GetValueVector2d().y);
00109 
00110   if (!_sdf->HasElement("joint4"))
00111   { //gzerr << "SimpleArm plugin missing <joint4> element\n";  
00112     ROS_FATAL("SimpleArm plugin missing <joint4> element\n");
00113     return;
00114   }
00115   this->joints_[3] = _model->GetJoint(_sdf->GetElement("joint4")->GetValueString());
00116   this->jointPIDs_[3] = common::PID(
00117     _sdf->GetElement("joint4_pid")->GetValueVector3().x,
00118     _sdf->GetElement("joint4_pid")->GetValueVector3().y,
00119     _sdf->GetElement("joint4_pid")->GetValueVector3().z,
00120     _sdf->GetElement("joint4_ilim")->GetValueVector2d().x,
00121     _sdf->GetElement("joint4_ilim")->GetValueVector2d().y,    
00122     _sdf->GetElement("joint4_cmdlim")->GetValueVector2d().x,
00123     _sdf->GetElement("joint4_cmdlim")->GetValueVector2d().y);
00124   
00125   if (!_sdf->HasElement("joint5"))
00126   { //gzerr << "SimpleArm plugin missing <joint5> element\n";
00127     ROS_FATAL("SimpleArm plugin missing <joint5> element\n");
00128   }
00129   
00130   this->joints_[4] = _model->GetJoint(_sdf->GetElement("joint5")->GetValueString());
00131   this->jointPIDs_[4] = common::PID(
00132     _sdf->GetElement("joint5_pid")->GetValueVector3().x,
00133     _sdf->GetElement("joint5_pid")->GetValueVector3().y,
00134     _sdf->GetElement("joint5_pid")->GetValueVector3().z,
00135     _sdf->GetElement("joint5_ilim")->GetValueVector2d().x,
00136     _sdf->GetElement("joint5_ilim")->GetValueVector2d().y,
00137     _sdf->GetElement("joint5_cmdlim")->GetValueVector2d().x,
00138     _sdf->GetElement("joint5_cmdlim")->GetValueVector2d().y);
00139  
00140   //ROS subscriber
00141   node_handle_ = new ros::NodeHandle(namespace_);
00142 
00143   //subscribe command
00144   if (!joints_topic_.empty())
00145   {
00146     ros::SubscribeOptions ops = ros::SubscribeOptions::create<sensor_msgs::JointState>(this->joints_topic_, 1, boost::bind(&SimpleArmPlugin::JointsCallback, this, _1), ros::VoidPtr(), &callback_queue_);
00147     this->joints_subscriber_ = node_handle_->subscribe(ops);
00148   }
00149    
00150   Reset(); 
00151   
00152   // New Mechanism for Updating every World Cycle
00153   // Listen to the update event. This event is broadcast every
00154   // simulation iteration.
00155   this->updateConnection_ = event::Events::ConnectWorldUpdateStart(
00156       boost::bind(&SimpleArmPlugin::Update, this));
00157 }
00158 
00160 // Callback
00161 void SimpleArmPlugin::JointsCallback(const sensor_msgs::JointStateConstPtr& _msg)
00162 {
00163   for (int i = 0; i < NUM_JOINTS; i++)
00164    {
00165      jointPositions_[i]=_msg->position[i];
00166      jointVelocities_[i]=_msg->velocity[i];
00167      jointMaxEfforts_[i]=_msg->effort[i];
00168    }
00169 }
00170 
00172 // Update
00173 void SimpleArmPlugin::Update()
00174 {
00175   // Get simulator time
00176   common::Time currTime = this->model_->GetWorld()->GetSimTime();
00177   common::Time stepTime = currTime - this->prevUpdateTime_;
00178   
00179   // Get new commands/state
00180   callback_queue_.callAvailable();
00181 
00182   for (int i = 0; i < NUM_JOINTS; i++)
00183   {
00184     // ignore everything else, get position and force only
00185     double pos_target = this->jointPositions_[i];
00186     double pos_curr = this->joints_[i]->GetAngle(0).GetAsRadian();
00187     double max_cmd = this->jointMaxEfforts_[i];
00188  
00189     double pos_err = pos_curr - pos_target;
00190  
00191     double effort_cmd = this->jointPIDs_[i].Update(pos_err, stepTime);
00192     effort_cmd = effort_cmd > max_cmd ? max_cmd : (effort_cmd < -max_cmd ? -max_cmd : effort_cmd);
00193     this->joints_[i]->SetForce(0, effort_cmd);
00194   }
00195   
00196   this->prevUpdateTime_ = currTime;
00197 }
00198 
00200 // Reset the controller
00201 void SimpleArmPlugin::Reset()
00202 {
00203   for (int i = 1; i < NUM_JOINTS; i++)
00204    {
00205     this->jointPIDs_[i] = common::PID(1, 0.1, 0.01, 0, 0, 3.1416, -3.1416);
00206     this->jointPositions_[i] = 0.0;
00207     this->jointVelocities_[i] = 0.0;
00208     this->jointMaxEfforts_[i] = 10;
00209    }
00210 }
00211 
00212 GZ_REGISTER_MODEL_PLUGIN(SimpleArmPlugin)
00213 
00214 }


arm_sim_controller
Author(s): Àngel Santamaria Navarro
autogenerated on Fri Dec 6 2013 22:15:43