18 #include <std_msgs/Float64.h> 20 #include <gazebo/common/Console.hh> 33 if (
char* env_dbg = std::getenv(
"VRX_DEBUG"))
35 gzdbg << std::string(env_dbg) <<std::endl;
36 if (std::string(env_dbg) ==
"false")
41 gzwarn <<
"VRX_DEBUG environment variable not set, defaulting to true" 44 this->
world = _parent;
46 if (!_sdf->HasElement(
"wind_obj") ||
47 !_sdf->GetElement(
"wind_obj"))
49 gzerr <<
"Did not find SDF parameter wind_obj" << std::endl;
53 sdf::ElementPtr windObjSDF = _sdf->GetElement(
"wind_obj");
57 if (!windObjSDF->HasElement(
"name") ||
58 !windObjSDF->GetElement(
"name")->GetValue())
60 gzerr << (
"Did not find SDF parameter name") << std::endl;
64 obj.
modelName = windObjSDF->GetElement(
"name")->Get<std::string>();
67 if (!windObjSDF->HasElement(
"link_name") ||
68 !windObjSDF->GetElement(
"link_name")->GetValue())
70 gzerr << (
"Did not find SDF parameter link_name") << std::endl;
74 obj.
linkName = windObjSDF->GetElement(
"link_name")->Get<std::string>();
77 if (!windObjSDF->HasElement(
"coeff_vector") ||
78 !windObjSDF->GetElement(
"coeff_vector")->GetValue())
80 gzerr << (
"Did not find SDF parameter coeff_vector") << std::endl;
84 obj.
windCoeff = windObjSDF->GetElement(
"coeff_vector")->
85 Get<ignition::math::Vector3d>();
88 gzdbg << obj.
modelName <<
" loaded" << std::endl;
89 windObjSDF = windObjSDF->GetNextElement(
"wind_obj");
93 if (_sdf->HasElement(
"wind_direction"))
95 double windAngle = _sdf->GetElement(
"wind_direction")->Get<
double>();
101 gzmsg <<
"Wind direction unit vector = " << this->
windDirection << std::endl;
103 if (_sdf->HasElement(
"wind_mean_velocity"))
106 _sdf->GetElement(
"wind_mean_velocity")->Get<
double>();
111 if (_sdf->HasElement(
"var_wind_gain_constants"))
114 _sdf->GetElement(
"var_wind_gain_constants")->Get<
double>();
117 gzmsg <<
"var wind gain constants = " << this->
gainConstant << std::endl;
119 if (_sdf->HasElement(
"var_wind_time_constants"))
122 _sdf->GetElement(
"var_wind_time_constants")->Get<
double>();
125 gzmsg <<
"var wind time constants = " << this->
timeConstant << std::endl;
127 if (_sdf->HasElement(
"update_rate"))
130 _sdf->GetElement(
"update_rate")->Get<
double>();
133 gzmsg <<
"update rate = " << this->
updateRate << std::endl;
136 unsigned int seed = std::random_device {}();
137 if (_sdf->HasElement(
"random_seed") &&
138 _sdf->GetElement(
"random_seed")->Get<
unsigned int>() != 0)
140 seed = _sdf->GetElement(
"random_seed")->Get<
unsigned int>();
143 gzmsg <<
"Random seed value = " << seed << std::endl;
148 gzmsg <<
"Var wind filter gain = " << this->
filterGain << std::endl;
151 #if GAZEBO_MAJOR_VERSION >= 8 179 #if GAZEBO_MAJOR_VERSION >= 8 180 if ((!i.init) && (this->world->ModelByName(i.modelName)))
183 if ((!i.init) && (this->
world->GetModel(i.modelName)))
186 gzdbg << i.modelName <<
" initialized" << std::endl;
189 #if GAZEBO_MAJOR_VERSION >= 8 190 i.model = this->
world->ModelByName(i.modelName);
192 i.model = this->
world->GetModel(i.modelName);
194 i.link = i.model->GetLink(i.linkName);
197 gzdbg << i.modelName <<
"'s link name: " << i.linkName
198 <<
" is invalid" << std::endl;
205 #if GAZEBO_MAJOR_VERSION >= 8 206 double currentTime = this->
world->SimTime().Double();
208 double currentTime = this->
world->GetSimTime().Double();
211 std::normal_distribution<double> dist(0, 1);
220 for (
auto& windObj : this->windObjs)
224 if (!windObj.init || !windObj.link)
228 #if GAZEBO_MAJOR_VERSION >= 8 229 ignition::math::Vector3d relativeWind =
230 windObj.link->WorldPose().Rot().Inverse().RotateVector(
233 ignition::math::Vector3d relativeWind =
234 windObj.link->GetWorldPose().rot.Ign().Inverse().RotateVector(
238 #if GAZEBO_MAJOR_VERSION >= 8 239 ignition::math::Vector3d apparentWind =
240 relativeWind - windObj.link->RelativeLinearVel();
242 ignition::math::Vector3d apparentWind = relativeWind
243 - windObj.link->GetRelativeLinearVel().Ign();
250 ignition::math::Vector3d windForce(
251 windObj.windCoeff.X() * relativeWind.X() * abs(relativeWind.X()),
252 windObj.windCoeff.Y() * relativeWind.Y() * abs(relativeWind.Y()),
253 -2.0 * windObj.windCoeff.Z() * relativeWind.X() * relativeWind.Y());
256 windObj.link->AddRelativeForce(
257 ignition::math::Vector3d(windForce.X(), windForce.Y(), 0.0));
258 windObj.link->AddRelativeTorque(
259 ignition::math::Vector3d(0.0, 0.0, windForce.Z()));
262 this->previousTime = currentTime;
271 publishingBuffer = -1;
276 std_msgs::Float64 windSpeedMsg;
277 std_msgs::Float64 windDirectionMsg;
278 windSpeedMsg.data = velocity;
279 windDirectionMsg.data =
double windMeanVelocity
Average wind velocity.
bool debug
Bool debug set by environment var VRX_DEBUG
GZ_REGISTER_WORLD_PLUGIN(UsvWindPlugin)
physics::WorldPtr world
Pointer to the Gazebo world.
unsigned int windObjsInitCount
Bool to keep track if ALL of the windObjs have been initialized.
std::vector< UsvWindPlugin::WindObj > windObjs
vector of simple objects effected by the wind
std::unique_ptr< ros::NodeHandle > rosNode
ROS node handle.
double filterGain
Calculated filter gain constant.
double lastPublishTime
Last time wind speed and direction was published.
A plugin that simulates a simple wind model. It accepts the following parameters: ...
double updateRate
Update rate buffer for wind speed and direction.
ros::Publisher windSpeedPub
Publisher for wind speed.
ignition::math::Vector3d windDirection
Wind velocity unit vector in Gazebo coordinates [m/s].
double previousTime
Previous time.
std::string linkName
of the link on that model
event::ConnectionPtr updateConnection
Pointer to the update event connection.
void publish(const boost::shared_ptr< M > &message) const
double timeConstant
Time constant.
bool windObjsInit
Bool to keep track if ALL of the windObjs have been initialized.
UsvWindPlugin()
Constructor.
double gainConstant
User specified gain constant.
virtual void Update()
Callback executed at every physics update.
std::unique_ptr< std::mt19937 > randGenerator
std::string topicWindDirection
Topic where the wind direction is published.
std::string topicWindSpeed
Topic where the wind speed is published.
double varVel
Variable velocity component.
ignition::math::Vector3d windCoeff
Wind force coefficients.
virtual void Load(physics::WorldPtr _parent, sdf::ElementPtr _sdf)
ros::Publisher windDirectionPub
Publisher for wind direction.