Go to the documentation of this file.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 #ifndef HECTOR_GAZEBO_PLUGINS_UPDATE_TIMER_H
00030 #define HECTOR_GAZEBO_PLUGINS_UPDATE_TIMER_H
00031
00032 #include <sdf/sdf.hh>
00033 #include <gazebo/physics/World.hh>
00034 #include <gazebo/physics/PhysicsEngine.hh>
00035
00036 #include <gazebo/common/Event.hh>
00037 #include <gazebo/common/Events.hh>
00038
00039 namespace gazebo {
00040
00041 class UpdateTimer {
00042 public:
00043 UpdateTimer()
00044 : connection_count_(0)
00045 {
00046 }
00047
00048 virtual ~UpdateTimer()
00049 {
00050 }
00051
00052 virtual void Load(physics::WorldPtr _world, sdf::ElementPtr _sdf, const std::string& _prefix = "update")
00053 {
00054 this->world_ = _world;
00055
00056 if (_sdf->HasElement(_prefix + "Rate")) {
00057 double update_rate = 0.0;
00058 _sdf->GetElement(_prefix + "Rate")->GetValue()->Get(update_rate);
00059 update_period_ = update_rate > 0.0 ? 1.0/update_rate : 0.0;
00060 }
00061
00062 if (_sdf->HasElement(_prefix + "Period")) {
00063 _sdf->GetElement(_prefix + "Period")->GetValue()->Get(update_period_);
00064 }
00065
00066 if (_sdf->HasElement(_prefix + "Offset")) {
00067 _sdf->GetElement(_prefix + "Offset")->GetValue()->Get(update_offset_);
00068 }
00069 }
00070
00071 virtual event::ConnectionPtr Connect(const boost::function<void()> &_subscriber, bool connectToWorldUpdateBegin = true)
00072 {
00073 if (connectToWorldUpdateBegin && !update_connection_) {
00074 update_connection_ = event::Events::ConnectWorldUpdateBegin(
00075 boost::bind(&UpdateTimer::Update, this));
00076 }
00077 connection_count_++;
00078 return update_event_.Connect(_subscriber);
00079 }
00080
00081 virtual void Disconnect(event::ConnectionPtr const& _c = event::ConnectionPtr())
00082 {
00083 if (_c) update_event_.Disconnect(_c);
00084
00085 if (update_connection_ && (!_c || --connection_count_ == 0)) {
00086 event::Events::DisconnectWorldUpdateBegin(update_connection_);
00087 update_connection_.reset();
00088 }
00089 }
00090
00091 common::Time const& getUpdatePeriod() const {
00092 return update_period_;
00093 }
00094
00095 void setUpdatePeriod(common::Time const& period) {
00096 update_period_ = period;
00097 }
00098
00099 double getUpdateRate() const {
00100 double period = update_period_.Double();
00101 return (period > 0.0) ? (1.0 / period) : 0.0;
00102 }
00103
00104 void setUpdateRate(double rate) {
00105 update_period_ = (rate > 0.0) ? (1.0 / rate) : 0.0;
00106 }
00107
00108 common::Time const& getLastUpdate() const {
00109 return last_update_;
00110 }
00111
00112 common::Time getTimeSinceLastUpdate() const {
00113 if (last_update_ == common::Time()) return common::Time();
00114 return world_->GetSimTime() - last_update_;
00115 }
00116
00117 virtual bool checkUpdate() const
00118 {
00119 double period = update_period_.Double();
00120 double step = world_->GetPhysicsEngine()->GetMaxStepSize();
00121 if (period == 0) return true;
00122 double fraction = fmod((world_->GetSimTime() - update_offset_).Double() + (step / 2.0), period);
00123 return (fraction >= 0.0) && (fraction < step);
00124 }
00125
00126 virtual bool update()
00127 {
00128 if (!checkUpdate()) return false;
00129 last_update_ = world_->GetSimTime();
00130 return true;
00131 }
00132
00133 virtual bool update(double& dt)
00134 {
00135 dt = getTimeSinceLastUpdate().Double();
00136 return update();
00137 }
00138
00139 virtual void Reset()
00140 {
00141 last_update_ = common::Time();
00142 }
00143
00144 protected:
00145 virtual bool Update()
00146 {
00147 if (!checkUpdate()) {
00148 return false;
00149 }
00150 update_event_();
00151 last_update_ = world_->GetSimTime();
00152 return true;
00153 }
00154
00155 private:
00156 physics::WorldPtr world_;
00157 common::Time update_period_;
00158 common::Time update_offset_;
00159 common::Time last_update_;
00160
00161 event::EventT<void()> update_event_;
00162 unsigned int connection_count_;
00163 event::ConnectionPtr update_connection_;
00164 };
00165
00166 }
00167
00168 #endif // HECTOR_GAZEBO_PLUGINS_UPDATE_TIMER_H