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 #include <algorithm>
00032 #include <assert.h>
00033
00034 #include <gazebo_plugins/gazebo_ros_sim_iface.h>
00035
00036 #include <gazebo/Sensor.hh>
00037 #include <gazebo/Model.hh>
00038 #include <gazebo/Global.hh>
00039 #include <gazebo/XMLConfig.hh>
00040 #include <gazebo/Simulator.hh>
00041 #include <gazebo/gazebo.h>
00042 #include <gazebo/World.hh>
00043 #include <gazebo/GazeboError.hh>
00044 #include <gazebo/ControllerFactory.hh>
00045
00046 using namespace gazebo;
00047
00048 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_sim_iface", GazeboRosSimIface);
00049
00051
00052 GazeboRosSimIface::GazeboRosSimIface(Entity *parent)
00053 : Controller(parent)
00054 {
00055 this->myParent = parent;
00056
00057 if (!this->myParent)
00058 gzthrow("GazeboRosSimIface controller requires an Entity as its parent");
00059
00060
00061 Param::Begin(&this->parameters);
00062 this->robotNamespaceP = new ParamT<std::string>("robotNamespace", "/", 0);
00063 this->topicNameP = new ParamT<std::string>("topicName","gazebo/set_pose", 0);
00064 this->serviceNameP = new ParamT<std::string>("serviceName","gazebo/set_pose", 0);
00065 this->modelNameP = new ParamT<std::string>("modelName","pr2_model", 1);
00066 this->xyzP = new ParamT<Vector3>("xyz" ,Vector3(0,0,0), 0);
00067 this->rpyP = new ParamT<Vector3>("rpy" ,Vector3(0,0,0), 0);
00068 this->velP = new ParamT<Vector3>("vel" ,Vector3(0,0,0), 0);
00069 this->angVelP = new ParamT<Vector3>("angVel" ,Vector3(0,0,0), 0);
00070 Param::End();
00071 }
00072
00074
00075 GazeboRosSimIface::~GazeboRosSimIface()
00076 {
00077 delete this->rosnode_;
00078
00079 delete this->robotNamespaceP;
00080 delete this->topicNameP;
00081 delete this->serviceNameP;
00082 delete this->modelNameP;
00083 delete this->xyzP;
00084 delete this->rpyP;
00085 delete this->velP;
00086 delete this->angVelP;
00087
00088 }
00089
00091
00092 void GazeboRosSimIface::LoadChild(XMLConfigNode *node)
00093 {
00094 this->robotNamespaceP->Load(node);
00095 this->robotNamespace = this->robotNamespaceP->GetValue();
00096 if (!ros::isInitialized())
00097 {
00098 int argc = 0;
00099 char** argv = NULL;
00100 ros::init(argc,argv,"gazebo",ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
00101 }
00102 this->rosnode_ = new ros::NodeHandle(this->robotNamespace);
00103
00104 this->topicNameP->Load(node);
00105 this->modelNameP->Load(node);
00106 this->xyzP->Load(node);
00107 this->rpyP->Load(node);
00108 this->velP->Load(node);
00109 this->angVelP->Load(node);
00110
00111 this->topicName = this->topicNameP->GetValue();
00112 this->modelName = this->modelNameP->GetValue();
00113 this->xyz = this->xyzP->GetValue();
00114 this->rpy = this->rpyP->GetValue();
00115 this->vel = this->velP->GetValue();
00116 this->angVel = this->angVelP->GetValue();
00117
00118
00119
00120 ros::SubscribeOptions so = ros::SubscribeOptions::create<nav_msgs::Odometry>(
00121 this->topicName,1,
00122 boost::bind( &GazeboRosSimIface::UpdateObjectPose,this,_1),
00123 ros::VoidPtr(), &this->queue_);
00124 this->sub_ = this->rosnode_->subscribe(so);
00125
00126 #if ROS_SIM_IFACE_EXPOSE_SERVICE
00127
00128 this->serviceNameP->Load(node);
00129 this->serviceName = this->serviceNameP->GetValue();
00130
00131 ros::AdvertiseServiceOptions aso = ros::AdvertiseServiceOptions::create<gazebo_plugins::SetPose>(
00132 this->serviceName,boost::bind( &GazeboRosSimIface::ServiceCallback, this, _1, _2 ), ros::VoidPtr(), &this->queue_);
00133 this->srv_ = this->rosnode_->advertiseService(aso);
00134 #endif
00135
00136 }
00137
00139
00140 bool GazeboRosSimIface::ServiceCallback(gazebo_plugins::SetPose::Request &req,
00141 gazebo_plugins::SetPose::Response &res)
00142 {
00143 Model* model = dynamic_cast<Model*>(gazebo::World::Instance()->GetEntityByName(this->modelName));
00144 if (model)
00145 {
00146 Vector3 target_pos(req.pose.pose.pose.position.x,req.pose.pose.pose.position.y,req.pose.pose.pose.position.z);
00147 Quatern target_rot(req.pose.pose.pose.orientation.w,req.pose.pose.pose.orientation.x,req.pose.pose.pose.orientation.y,req.pose.pose.pose.orientation.z);
00148 Pose3d target_pose(target_pos,target_rot);
00149
00150 this->frameName = req.pose.header.frame_id;
00151
00152 this->myFrame = NULL;
00155 if (this->frameName != "world" && this->frameName != "/map" && this->frameName != "map")
00156 {
00157
00158 boost::recursive_mutex::scoped_lock lock(*Simulator::Instance()->GetMRMutex());
00159
00160 std::vector<Model*> all_models = World::Instance()->GetModels();
00161 for (std::vector<Model*>::iterator iter = all_models.begin(); iter != all_models.end(); iter++)
00162 {
00163 if (*iter) this->myFrame = dynamic_cast<Body*>((*iter)->GetBody(this->frameName));
00164 if (this->myFrame) break;
00165 }
00166
00167
00168 if (this->myFrame == NULL)
00169 {
00170 ROS_DEBUG("gazebo_ros_sim_iface plugin: frame_id: %s does not exist in simulation, will not set pose\n",this->frameName.c_str());
00171 return false;
00172 }
00173 }
00174
00175
00176
00177 if (this->myFrame)
00178 {
00179 Pose3d frame_pose = this->myFrame->GetWorldPose();
00180 Vector3 frame_pos = frame_pose.pos;
00181 Quatern frame_rot = frame_pose.rot;
00182
00183
00184
00185 target_pose.pos = frame_pos + frame_rot.RotateVector(target_pos);
00186 target_pose.rot *= frame_rot;
00187 }
00188
00189
00190 {
00191
00192 Simulator::Instance()->SetPaused(true);
00193 this->lock.lock();
00194
00195 model->SetWorldPose(target_pose);
00196
00197
00198 Vector3 vel(0,0,0);
00199 model->SetLinearVel(vel);
00200 model->SetAngularVel(vel);
00201
00202 this->lock.unlock();
00203 Simulator::Instance()->SetPaused(false);
00204 }
00205
00206 return true;
00207 }
00208 else
00209 {
00210 res.status_message = "trying to set pose of a model that does not exist";
00211 return false;
00212 }
00213 }
00214
00216
00217 void GazeboRosSimIface::InitChild()
00218 {
00219
00220 this->callback_queue_thread_ = boost::thread( boost::bind( &GazeboRosSimIface::QueueThread,this ) );
00221 }
00222
00224
00225 void GazeboRosSimIface::UpdateObjectPose(const nav_msgs::Odometry::ConstPtr& poseMsg)
00226 {
00227 Model* model = dynamic_cast<Model*>(gazebo::World::Instance()->GetEntityByName(this->modelName));
00228 if (model)
00229 {
00230
00231 Vector3 target_pos(poseMsg->pose.pose.position.x,poseMsg->pose.pose.position.y,poseMsg->pose.pose.position.z);
00232 Quatern target_rot(poseMsg->pose.pose.orientation.w,poseMsg->pose.pose.orientation.x,poseMsg->pose.pose.orientation.y,poseMsg->pose.pose.orientation.z);
00233 Pose3d target_pose(target_pos,target_rot);
00234
00235 this->frameName = poseMsg->header.frame_id;
00236
00237 this->myFrame = NULL;
00238
00239 if (this->frameName != "world")
00240 {
00241
00242 boost::recursive_mutex::scoped_lock lock(*Simulator::Instance()->GetMRMutex());
00243
00244 std::vector<Model*> all_models = World::Instance()->GetModels();
00245 for (std::vector<Model*>::iterator iter = all_models.begin(); iter != all_models.end(); iter++)
00246 {
00247 if (*iter) this->myFrame = dynamic_cast<Body*>((*iter)->GetBody(this->frameName));
00248 if (this->myFrame) break;
00249 }
00250
00251
00252 if (this->myFrame == NULL)
00253 {
00254 ROS_DEBUG("gazebo_ros_sim_iface plugin: frame_id: %s does not exist in simulation, will not set pose\n",this->frameName.c_str());
00255 return;
00256 }
00257 }
00258
00259
00260
00261 if (this->myFrame)
00262 {
00263 Pose3d frame_pose = this->myFrame->GetWorldPose();
00264 Vector3 frame_pos = frame_pose.pos;
00265 Quatern frame_rot = frame_pose.rot;
00266
00267
00268 target_pose.pos = frame_pos + frame_rot.RotateVector(target_pos);
00269 target_pose.rot *= frame_rot;
00270 }
00271
00272
00273
00274
00275 {
00276 Simulator::Instance()->SetPaused(true);
00277 this->lock.lock();
00278
00279 model->SetWorldPose(target_pose);
00280
00281 Vector3 vel(0,0,0);
00282 boost::recursive_mutex::scoped_lock lock(*Simulator::Instance()->GetMRMutex());
00283 model->SetLinearVel(vel);
00284 model->SetAngularVel(vel);
00285
00286 this->lock.unlock();
00287 Simulator::Instance()->SetPaused(false);
00288 }
00289
00290 }
00291 else
00292 {
00293 ROS_INFO("Trying to set pose of a model [%s] that does not exist",this->modelName.c_str());
00294 }
00295 }
00296
00298
00299 void GazeboRosSimIface::UpdateChild()
00300 {
00301
00302
00303
00304 }
00305
00307
00308 void GazeboRosSimIface::FiniChild()
00309 {
00310
00311 this->queue_.clear();
00312 this->queue_.disable();
00313 this->rosnode_->shutdown();
00314 this->callback_queue_thread_.join();
00315 }
00316
00317
00319
00320 void GazeboRosSimIface::QueueThread()
00321 {
00322 static const double timeout = 0.01;
00323
00324 while (this->rosnode_->ok())
00325 {
00326 this->queue_.callAvailable(ros::WallDuration(timeout));
00327 }
00328 }
00329
00330
00331