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 #include <algorithm>
00030 #include <assert.h>
00031
00032 #include <gazebo_plugins/gazebo_ros_pub_world_state.h>
00033
00034 #include <gazebo/Global.hh>
00035 #include <gazebo/XMLConfig.hh>
00036 #include <gazebo/gazebo.h>
00037 #include <gazebo/GazeboError.hh>
00038 #include <gazebo/ControllerFactory.hh>
00039 #include <boost/bind.hpp>
00040
00041 using namespace gazebo;
00042
00043 GZ_REGISTER_DYNAMIC_CONTROLLER("gazebo_ros_pub_world_state", GazeboRosPubWorldState);
00044
00046
00047 GazeboRosPubWorldState::GazeboRosPubWorldState(Entity *parent)
00048 : Controller(parent)
00049 {
00050 this->parent_model_ = dynamic_cast<Model*>(this->parent);
00051
00052 if (!this->parent_model_)
00053 gzthrow("GazeboMechanismControl controller requires a Model as its parent");
00054
00055 Param::Begin(&this->parameters);
00056 this->robotNamespaceP = new ParamT<std::string>("robotNamespace", "/", 0);
00057 this->topicNameP = new ParamT<std::string>("topicName", "", 1);
00058 this->frameNameP = new ParamT<std::string>("frameName", "base_link", 0);
00059 Param::End();
00060
00061 this->worldStateConnectCount = 0;
00062 }
00063
00065
00066 GazeboRosPubWorldState::~GazeboRosPubWorldState()
00067 {
00068 delete this->robotNamespaceP;
00069 delete this->topicNameP;
00070 delete this->frameNameP;
00071 delete this->rosnode_;
00072 }
00073
00075
00076 void GazeboRosPubWorldState::LoadChild(XMLConfigNode *node)
00077 {
00078 this->robotNamespaceP->Load(node);
00079 this->robotNamespace = this->robotNamespaceP->GetValue();
00080
00081 if (!ros::isInitialized())
00082 {
00083 int argc = 0;
00084 char** argv = NULL;
00085 ros::init(argc,argv,"gazebo",ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
00086 }
00087
00088 this->rosnode_ = new ros::NodeHandle(this->robotNamespace);
00089
00090 this->topicNameP->Load(node);
00091 this->topicName = this->topicNameP->GetValue();
00092 this->frameNameP->Load(node);
00093 this->frameName = this->frameNameP->GetValue();
00094
00095
00096 ros::AdvertiseOptions ao = ros::AdvertiseOptions::create<gazebo_plugins::WorldState>(
00097 this->topicName,1,
00098 boost::bind( &GazeboRosPubWorldState::WorldStateConnect,this),
00099 boost::bind( &GazeboRosPubWorldState::WorldStateDisconnect,this), ros::VoidPtr(), &this->queue_);
00100 this->pub_ = this->rosnode_->advertise(ao);
00101
00102 }
00103
00105
00106 void GazeboRosPubWorldState::WorldStateConnect()
00107 {
00108 this->worldStateConnectCount++;
00109 }
00110
00112
00113 void GazeboRosPubWorldState::WorldStateDisconnect()
00114 {
00115 this->worldStateConnectCount--;
00116 }
00117
00119
00120 void GazeboRosPubWorldState::InitChild()
00121 {
00122
00123 this->callback_queue_thread_ = boost::thread( boost::bind( &GazeboRosPubWorldState::QueueThread,this ) );
00124 }
00125
00127
00128 void GazeboRosPubWorldState::UpdateChild()
00129 {
00130
00131
00132
00133
00134
00135 if (this->worldStateConnectCount == 0)
00136 return;
00137
00138
00139
00140
00141
00142
00143 Time cur_time = Simulator::Instance()->GetSimTime();
00144
00146 std::vector<gazebo::Model*> models;
00147 std::vector<gazebo::Model*>::iterator miter;
00148
00150 std::map<std::string,gazebo::Body*> all_bodies;
00151 all_bodies.clear();
00152
00153 models = gazebo::World::Instance()->GetModels();
00154
00155
00156 for (miter = models.begin(); miter != models.end(); miter++)
00157 {
00158 const std::vector<gazebo::Entity*> entities = (*miter)->GetChildren();
00159
00160 std::vector<Entity*>::const_iterator eiter;
00161 for (eiter=entities.begin(); eiter!=entities.end(); eiter++)
00162 {
00163 gazebo::Body* body = dynamic_cast<gazebo::Body*>(*eiter);
00164 if (body)
00165 all_bodies.insert(make_pair(body->GetName(),body));
00166 }
00167 }
00168
00169
00170
00171 if (!all_bodies.empty())
00172 {
00173 this->lock.lock();
00174
00175
00176 this->worldStateMsg.header.frame_id = this->frameName;
00177 this->worldStateMsg.header.stamp.fromSec(cur_time.Double());
00178
00179
00180 std::map<std::string, Body*>::iterator biter;
00181 for (biter=all_bodies.begin(); biter!=all_bodies.end(); biter++)
00182 {
00183
00184
00185 this->worldStateMsg.name.push_back(std::string(biter->second->GetName()));
00186
00187
00188
00189 Pose3d pose;
00190 Quatern rot;
00191 Vector3 pos;
00192
00193 pose = (biter->second)->GetWorldPose();
00194
00195
00196 pos = pose.pos;
00197 rot = pose.rot;
00198
00199
00200
00201
00202
00203
00204
00205 geometry_msgs::Pose geom_pose;
00206 geom_pose.position.x = pos.x;
00207 geom_pose.position.y = pos.y;
00208 geom_pose.position.z = pos.z;
00209 geom_pose.orientation.x = rot.x;
00210 geom_pose.orientation.y = rot.y;
00211 geom_pose.orientation.z = rot.z;
00212 geom_pose.orientation.w = rot.u;
00213 this->worldStateMsg.pose.push_back(geom_pose);
00214
00215
00216
00217 Vector3 vpos = (biter->second)->GetWorldLinearVel();
00218 Vector3 veul = (biter->second)->GetWorldAngularVel();
00219
00220
00221 geometry_msgs::Twist geom_twist;
00222 geom_twist.linear.x = vpos.x;
00223 geom_twist.linear.y = vpos.y;
00224 geom_twist.linear.z = vpos.z;
00225
00226 geom_twist.angular.x = veul.x;
00227 geom_twist.angular.y = veul.y;
00228 geom_twist.angular.z = veul.z;
00229 this->worldStateMsg.twist.push_back(geom_twist);
00230
00231
00232 Vector3 force = (biter->second)->GetWorldForce();
00233 Vector3 torque = (biter->second)->GetWorldTorque();
00234 geometry_msgs::Wrench geom_wrench;
00235 geom_wrench.force.x = force.x;
00236 geom_wrench.force.y = force.y;
00237 geom_wrench.force.z = force.z;
00238 geom_wrench.torque.x = torque.x;
00239 geom_wrench.torque.y = torque.y;
00240 geom_wrench.torque.z = torque.z;
00241 this->worldStateMsg.wrench.push_back(geom_wrench);
00242
00243 }
00244 this->pub_.publish(this->worldStateMsg);
00245 this->lock.unlock();
00246
00247 }
00248 }
00249
00251
00252 void GazeboRosPubWorldState::FiniChild()
00253 {
00254
00255 this->queue_.clear();
00256 this->queue_.disable();
00257 this->rosnode_->shutdown();
00258 this->callback_queue_thread_.join();
00259 }
00260
00261
00262
00264
00265 void GazeboRosPubWorldState::QueueThread()
00266 {
00267 static const double timeout = 0.01;
00268
00269 while (this->rosnode_->ok())
00270 {
00271 this->queue_.callAvailable(ros::WallDuration(timeout));
00272 }
00273 }
00274
00275