gazebo_pressure_plugin.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2016 Pavel Vechersky, ASL, ETH Zurich, Switzerland
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 // MODULE HEADER
00018 #include "rotors_gazebo_plugins/gazebo_pressure_plugin.h"
00019 
00020 // USER HEADERS
00021 #include "ConnectGazeboToRosTopic.pb.h"
00022 
00023 namespace gazebo {
00024 
00025 GazeboPressurePlugin::GazeboPressurePlugin()
00026     : ModelPlugin(),
00027       node_handle_(0),
00028       pubs_and_subs_created_(false) {
00029 }
00030 
00031 GazeboPressurePlugin::~GazeboPressurePlugin() {
00032 }
00033 
00034 void GazeboPressurePlugin::Load(physics::ModelPtr _model, sdf::ElementPtr _sdf) {
00035   if (kPrintOnPluginLoad) {
00036     gzdbg << __FUNCTION__ << "() called." << std::endl;
00037   }
00038 
00039   gzdbg << "_model = " << _model->GetName() << std::endl;
00040 
00041   // Store the pointer to the model and the world.
00042   model_ = _model;
00043   world_ = model_->GetWorld();
00044 
00045   //==============================================//
00046   //========== READ IN PARAMS FROM SDF ===========//
00047   //==============================================//
00048 
00049   // Use the robot namespace to create the node handle.
00050   if (_sdf->HasElement("robotNamespace"))
00051     namespace_ = _sdf->GetElement("robotNamespace")->Get<std::string>();
00052   else
00053     gzerr << "[gazebo_pressure_plugin] Please specify a robotNamespace.\n";
00054 
00055   // Get node handle.
00056   node_handle_ = transport::NodePtr(new transport::Node());
00057 
00058   // Initialise with default namespace (typically /gazebo/default/).
00059   node_handle_->Init();
00060 
00061   std::string link_name;
00062   if (_sdf->HasElement("linkName"))
00063     link_name = _sdf->GetElement("linkName")->Get<std::string>();
00064   else
00065     gzerr << "[gazebo_pressure_plugin] Please specify a linkName.\n";
00066   // Get the pointer to the link.
00067   link_ = model_->GetLink(link_name);
00068   if (link_ == NULL)
00069     gzthrow("[gazebo_pressure_plugin] Couldn't find specified link \"" << link_name << "\".");
00070 
00071   frame_id_ = link_name;
00072 
00073   // Retrieve the rest of the SDF parameters.
00074   getSdfParam<std::string>(_sdf, "pressureTopic", pressure_topic_, kDefaultPressurePubTopic);
00075   getSdfParam<double>(_sdf, "referenceAltitude", ref_alt_, kDefaultRefAlt);
00076   getSdfParam<double>(_sdf, "pressureVariance", pressure_var_, kDefaultPressureVar);
00077   CHECK(pressure_var_ >= 0.0);
00078 
00079   // Initialize the normal distribution for pressure.
00080   double mean = 0.0;
00081   pressure_n_[0] = NormalDistribution(mean, sqrt(pressure_var_));
00082 
00083   // Listen to the update event. This event is broadcast every simulation
00084   // iteration.
00085   this->updateConnection_ = event::Events::ConnectWorldUpdateBegin(
00086       boost::bind(&GazeboPressurePlugin::OnUpdate, this, _1));
00087 
00088   //==============================================//
00089   //=== POPULATE STATIC PARTS OF PRESSURE MSG ====//
00090   //==============================================//
00091 
00092   pressure_message_.mutable_header()->set_frame_id(frame_id_);
00093   pressure_message_.set_variance(pressure_var_);
00094 }
00095 
00096 void GazeboPressurePlugin::OnUpdate(const common::UpdateInfo& _info) {
00097   if (kPrintOnUpdates) {
00098     gzdbg << __FUNCTION__ << "() called." << std::endl;
00099   }
00100 
00101   if (!pubs_and_subs_created_) {
00102     CreatePubsAndSubs();
00103     pubs_and_subs_created_ = true;
00104   }
00105 
00106   common::Time current_time = world_->SimTime();
00107 
00108   // Get the current geometric height.
00109   double height_geometric_m = ref_alt_ + model_->WorldPose().Pos().Z();
00110 
00111   // Compute the geopotential height.
00112   double height_geopotential_m = kEarthRadiusMeters * height_geometric_m /
00113       (kEarthRadiusMeters + height_geometric_m);
00114 
00115   // Compute the temperature at the current altitude.
00116   double temperature_at_altitude_kelvin =
00117       kSeaLevelTempKelvin - kTempLapseKelvinPerMeter * height_geopotential_m;
00118 
00119   // Compute the current air pressure.
00120   double pressure_at_altitude_pascal =
00121       kPressureOneAtmospherePascals * exp(kAirConstantDimensionless *
00122           log(kSeaLevelTempKelvin / temperature_at_altitude_kelvin));
00123 
00124   // Add noise to pressure measurement.
00125   if(pressure_var_ > 0.0) {
00126     pressure_at_altitude_pascal += pressure_n_[0](random_generator_);
00127   }
00128 
00129   // Fill the pressure message.
00130   pressure_message_.mutable_header()->mutable_stamp()->set_sec(
00131       current_time.sec);
00132   pressure_message_.mutable_header()->mutable_stamp()->set_nsec(
00133       current_time.nsec);
00134   pressure_message_.set_fluid_pressure(pressure_at_altitude_pascal);
00135 
00136   // Publish the pressure message.
00137   pressure_pub_->Publish(pressure_message_);
00138 }
00139 
00140 void GazeboPressurePlugin::CreatePubsAndSubs() {
00141   // Create temporary "ConnectGazeboToRosTopic" publisher and message.
00142   gazebo::transport::PublisherPtr connect_gazebo_to_ros_topic_pub =
00143       node_handle_->Advertise<gz_std_msgs::ConnectGazeboToRosTopic>(
00144           "~/" + kConnectGazeboToRosSubtopic, 1);
00145 
00146   // ============================================ //
00147   // ========= FLUID PRESSURE MSG SETUP ========= //
00148   // ============================================ //
00149 
00150   pressure_pub_ = node_handle_->Advertise<gz_sensor_msgs::FluidPressure>(
00151       "~/" + namespace_ + "/" + pressure_topic_, 1);
00152 
00153   gz_std_msgs::ConnectGazeboToRosTopic connect_gazebo_to_ros_topic_msg;
00154   connect_gazebo_to_ros_topic_msg.set_gazebo_topic("~/" + namespace_ + "/" +
00155                                                    pressure_topic_);
00156   connect_gazebo_to_ros_topic_msg.set_ros_topic(namespace_ + "/" +
00157                                                 pressure_topic_);
00158   connect_gazebo_to_ros_topic_msg.set_msgtype(
00159       gz_std_msgs::ConnectGazeboToRosTopic::FLUID_PRESSURE);
00160   connect_gazebo_to_ros_topic_pub->Publish(connect_gazebo_to_ros_topic_msg,
00161                                            true);
00162 }
00163 
00164 GZ_REGISTER_MODEL_PLUGIN(GazeboPressurePlugin);
00165 
00166 }  // namespace gazebo


rotors_gazebo_plugins
Author(s): Fadri Furrer, Michael Burri, Mina Kamel, Janosch Nikolic, Markus Achtelik
autogenerated on Thu Apr 18 2019 02:43:43