00001 #include "../include/RobotController.h"
00002
00003 #include "physics/Model.hh"
00004 #include "physics/World.hh"
00005 #include "physics/Joint.hh"
00006 #include "physics/Link.hh"
00007
00008 #include <ros/ros.h>
00009
00010 #include "nasa_r2_common_msgs/JointStatusArray.h"
00011
00012 using namespace gazebo;
00013
00014 RobotController::RobotController(physics::ModelPtr _modelPtr)
00015 : modelPtr(_modelPtr)
00016 {
00017 prevUpdateTime = _modelPtr->GetWorld()->GetSimTime();
00018 }
00019
00020 RobotController::~RobotController()
00021 {
00022 }
00023
00024 void RobotController::addJoint(physics::JointPtr _jointPtr, bool advancedMode)
00025 {
00026 boost::mutex::scoped_lock(pidMutex);
00027 JointControllerPtr jointPtr(new JointController(_jointPtr, advancedMode));
00028 joints[_jointPtr->GetName()] = jointPtr;
00029 }
00030
00031 void RobotController::addJointDependency(std::string _childName, std::string _parentName, double factor)
00032 {
00033 if (joints.find(_parentName) == joints.end())
00034 {
00035 ROS_WARN("GazeboInterface joint dependency not set because parent (%s) not found", _parentName.c_str());
00036 return;
00037 }
00038 if (joints.find(_childName) == joints.end())
00039 {
00040 ROS_WARN("GazeboInterface joint dependency not set because child (%s) not found", _childName.c_str());
00041 return;
00042 }
00043 boost::mutex::scoped_lock(pidMutex);
00044 dependencies.insert(std::make_pair(_parentName, std::make_pair(_childName, factor)));
00045 }
00046
00047 void RobotController::setPosPid(const std::string& name, double _p, double _i, double _d,
00048 double _imax, double _imin, double _cmdMax, double _cmdMin)
00049 {
00050 if (joints.find(name) == joints.end())
00051 {
00052 ROS_DEBUG("GazeboInterface PosPID not set because joint (%s) not found", name.c_str());
00053 return;
00054 }
00055 boost::mutex::scoped_lock(pidMutex);
00056 joints[name]->setPosPid(_p, _i, _d, _imax, _imin, _cmdMax, _cmdMin);
00057 }
00058
00059 void RobotController::setVelPid(const std::string& name, double _p, double _i, double _d,
00060 double _imax, double _imin, double _cmdMax, double _cmdMin)
00061 {
00062 if (joints.find(name) == joints.end())
00063 {
00064 ROS_WARN("GazeboInterface PosPID not set because joint (%s) not found", name.c_str());
00065 return;
00066 }
00067 boost::mutex::scoped_lock(pidMutex);
00068 joints[name]->setVelPid(_p, _i, _d, _imax, _imin, _cmdMax, _cmdMin);
00069 }
00070
00071
00072 void RobotController::setJointPositions(std::map<std::string, double> posMap)
00073 {
00074
00075 bool is_paused = modelPtr->GetWorld()->IsPaused();
00076 if (!is_paused) modelPtr->GetWorld()->SetPaused(true);
00077
00078
00079 std::map<std::string, bool> brakeStates;
00080 for (std::map<std::string, JointControllerPtr>::iterator it = joints.begin(); it != joints.end(); ++it)
00081 {
00082 brakeStates[it->first] = it->second->getJointStatus().brakeReleased;
00083 it->second->releaseBrake();
00084 }
00085
00086
00087 for (std::map<std::string, double>::iterator posIt = posMap.begin(); posIt != posMap.end(); ++posIt)
00088 {
00089 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(posIt->first);
00090 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00091 {
00092 posMap[depIt->second.first] = depIt->second.second * posIt->second;
00093 }
00094 }
00095
00096
00097 modelPtr->SetJointPositions(posMap);
00098
00099
00100 for (std::map<std::string, bool>::iterator it = brakeStates.begin(); it != brakeStates.end(); ++it)
00101 {
00102 joints[it->first]->releaseBrake(it->second);
00103 }
00104
00105
00106 modelPtr->GetWorld()->SetPaused(is_paused);
00107 }
00108
00109 void RobotController::getJointStates(std::map<std::string, JointState>& posMap)
00110 {
00111 if (posMap.empty())
00112 {
00113 JointState zero;
00114 zero.position = 0.;
00115 zero.velocity = 0.;
00116 zero.effort = 0.;
00117
00118
00119 for (std::map<std::string, JointControllerPtr>::const_iterator it = joints.begin(); it != joints.end(); ++it)
00120 {
00121 posMap[it->first] = zero;
00122 }
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133 if (!posMap.empty())
00134 {
00135 getJointStates(posMap);
00136 }
00137 }
00138
00139 for (unsigned int i = 0; i < modelPtr->GetJointCount(); ++i)
00140 {
00141 physics::JointPtr jPtr = modelPtr->GetJoint(i);
00142
00143
00144 std::string name = jPtr->GetName();
00145 std::map<std::string, JointState>::iterator it = posMap.find(name);
00146 if (it != posMap.end())
00147 {
00148 it->second.position = jPtr->GetAngle(0).GetAsRadian();
00149 it->second.velocity = jPtr->GetVelocity(0);
00150 it->second.effort = jPtr->GetForce(0);
00151 }
00152 }
00153 }
00154
00155 void RobotController::getJointTargets(std::map<std::string, JointState>& posMap)
00156 {
00157 if (posMap.empty())
00158 {
00159 JointState zero;
00160 zero.position = 0.;
00161 zero.velocity = 0.;
00162 zero.effort = 0.;
00163
00164
00165 for (std::map<std::string, JointControllerPtr>::const_iterator it = joints.begin(); it != joints.end(); ++it)
00166 {
00167 posMap[it->first] = zero;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 if (!posMap.empty())
00180 {
00181 getJointTargets(posMap);
00182 }
00183 }
00184
00185 for (std::map<std::string, JointControllerPtr>::const_iterator jIt = joints.begin(); jIt != joints.end(); ++jIt)
00186 {
00187 std::map<std::string, JointState>::iterator it = posMap.find(jIt->first);
00188 if (it != posMap.end())
00189 {
00190 it->second.position = jIt->second->getPosTarget();
00191 it->second.velocity = jIt->second->getVelTarget();
00192 it->second.effort = jIt->second->getEffortTarget();
00193
00194
00195 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(jIt->first);
00196 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00197 {
00198 if(depIt->second.second!=0)
00199 {
00200 it->second.position=it->second.position/depIt->second.second;
00201
00202 }
00203 }
00204 }
00205 }
00206 }
00207
00208 void RobotController::getJointLimits(std::map<std::string, std::pair<double, double> >& limitsMap)
00209 {
00210 if (limitsMap.empty())
00211 {
00212
00213 for (std::map<std::string, JointControllerPtr>::const_iterator it = joints.begin(); it != joints.end(); ++it)
00214 {
00215 limitsMap[it->first] = std::pair<double, double>(-3.14159, 3.14159);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 if (!limitsMap.empty())
00228 {
00229 getJointLimits(limitsMap);
00230 }
00231 }
00232
00233 for (std::map<std::string, JointControllerPtr>::const_iterator jIt = joints.begin(); jIt != joints.end(); ++jIt)
00234 {
00235 std::map<std::string, std::pair<double, double> >::iterator it = limitsMap.find(jIt->first);
00236 if (it != limitsMap.end())
00237 {
00238 jIt->second->getJointLimits(it->second.first, it->second.second);
00239 }
00240 }
00241 }
00242
00243 void RobotController::setJointPosTarget(const std::string& name, double target)
00244 {
00245 if (joints.find(name) == joints.end())
00246 {
00247
00248 return;
00249 }
00250 boost::mutex::scoped_lock(pidMutex);
00251 joints[name]->setPosTarget(target);
00252
00253
00254 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(name);
00255 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00256 {
00257 joints[depIt->second.first]->setPosTarget(depIt->second.second * target);
00258 }
00259 }
00260
00261 void RobotController::setJointVelTarget(const std::string& name, double target)
00262 {
00263 if (joints.find(name) == joints.end())
00264 {
00265 ROS_WARN("GazeboInterface setJointVelTarget not set because joint (%s) not found", name.c_str());
00266 return;
00267 }
00268 boost::mutex::scoped_lock(pidMutex);
00269 joints[name]->setVelTarget(target);
00270
00271
00272 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(name);
00273 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00274 {
00275 joints[depIt->second.first]->setVelTarget(depIt->second.second * target);
00276 }
00277 }
00278
00279 void RobotController::setJointEffortTarget(const std::string& name, double target)
00280 {
00281 if (joints.find(name) == joints.end())
00282 {
00283 ROS_WARN("GazeboInterface setJointEffortTarget not set because joint (%s) not found", name.c_str());
00284 return;
00285 }
00286 boost::mutex::scoped_lock(pidMutex);
00287 joints[name]->setEffortTarget(target);
00288
00289
00290 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(name);
00291 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00292 {
00293 joints[depIt->second.first]->setEffortTarget(depIt->second.second * target);
00294 }
00295 }
00296
00297
00298 void RobotController::setJointControl(const nasa_r2_common_msgs::JointControl::ConstPtr& msg)
00299 {
00300 if (joints.find(msg->joint) == joints.end())
00301 {
00302 ROS_WARN("GazeboInterface setJointControl not set because joint (%s) not found", msg->joint.c_str());
00303 return;
00304 }
00305 boost::mutex::scoped_lock(pidMutex);
00306 joints[msg->joint]->setJointControl(msg);
00307
00308
00309 std::pair<dependenciesType::iterator, dependenciesType::iterator> deps = dependencies.equal_range(msg->joint);
00310 for (dependenciesType::iterator depIt = deps.first; depIt != deps.second; ++depIt)
00311 {
00312 nasa_r2_common_msgs::JointControl* jcPtr = new nasa_r2_common_msgs::JointControl(*msg);
00313 jcPtr->joint = depIt->second.first;
00314 nasa_r2_common_msgs::JointControl::ConstPtr depJointControlPtr(jcPtr);
00315 joints[depIt->second.first]->setJointControl(depJointControlPtr);
00316 }
00317 }
00318
00319 const nasa_r2_common_msgs::JointStatus& RobotController::getJointStatus(const std::string& name) const
00320 {
00321 std::map<std::string, JointControllerPtr>::const_iterator cit = joints.find(name);
00322 if (cit == joints.end())
00323 {
00324 ROS_WARN("GazeboInterface getJointStatus failed because joint (%s) not found", name.c_str());
00325 }
00326 return cit->second->getJointStatus();
00327 }
00328
00329 void RobotController::update()
00330 {
00331 common::Time currTime = modelPtr->GetWorld()->GetSimTime();
00332 common::Time stepTime = currTime - prevUpdateTime;
00333 prevUpdateTime = currTime;
00334
00335 for (std::map<std::string, JointControllerPtr>::iterator it = joints.begin(); it != joints.end(); ++it)
00336 {
00337 it->second->update(stepTime);
00338 }
00339 }
00340
00341 void RobotController::publishJointStatuses(ros::Publisher& rosPub) const
00342 {
00343 nasa_r2_common_msgs::JointStatusArray statusArray;
00344 statusArray.header.stamp = ros::Time::now();
00345 for (std::map<std::string, JointControllerPtr>::const_iterator it = joints.begin(); it != joints.end(); ++it)
00346 {
00347 statusArray.status.push_back(it->second->getJointStatus());
00348 }
00349 rosPub.publish(statusArray);
00350 }