Skip to content

Commit 782d3d9

Browse files
committed
Fixedwing related plugins
This commit merges in fixedwing related plugins
1 parent 7f6b552 commit 782d3d9

15 files changed

+4602
-0
lines changed

rotors_gazebo_plugins/CMakeLists.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,27 @@ if (NOT NO_ROS)
301301
endif()
302302
list(APPEND targets_to_install rotors_gazebo_fw_dynamics_plugin)
303303

304+
add_library(rotors_gazebo_aerodynamics_plugin SHARED src/gazebo_aerodynamics_plugin.cpp)
305+
target_link_libraries(rotors_gazebo_aerodynamics_plugin ${target_linking_LIBRARIES} ${YamlCpp_LIBRARIES})
306+
if (NOT NO_ROS)
307+
add_dependencies(rotors_gazebo_aerodynamics_plugin ${catkin_EXPORTED_TARGETS})
308+
endif()
309+
list(APPEND targets_to_install rotors_gazebo_aerodynamics_plugin)
310+
311+
add_library(rotors_gazebo_wind_beta_plugin SHARED src/gazebo_wind_beta_plugin.cpp)
312+
target_link_libraries(rotors_gazebo_wind_beta_plugin ${target_linking_LIBRARIES} ${YamlCpp_LIBRARIES})
313+
if (NOT NO_ROS)
314+
add_dependencies(rotors_gazebo_wind_beta_plugin ${catkin_EXPORTED_TARGETS})
315+
endif()
316+
list(APPEND targets_to_install rotors_gazebo_wind_beta_plugin)
317+
318+
add_library(rotors_gazebo_propulsion_plugin SHARED src/gazebo_propulsion_plugin.cpp)
319+
target_link_libraries(rotors_gazebo_propulsion_plugin ${target_linking_LIBRARIES} ${YamlCpp_LIBRARIES})
320+
if (NOT NO_ROS)
321+
add_dependencies(rotors_gazebo_propulsion_plugin ${catkin_EXPORTED_TARGETS})
322+
endif()
323+
list(APPEND targets_to_install rotors_gazebo_propulsion_plugin)
324+
304325
#========================================= GPS PLUGIN ===========================================//
305326
add_library(rotors_gazebo_gps_plugin SHARED src/gazebo_gps_plugin.cpp)
306327
target_link_libraries(rotors_gazebo_gps_plugin ${target_linking_LIBRARIES} )
Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
1+
/*
2+
* Copyright (C) 2014-2016 Open Source Robotics Foundation
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
*
17+
* Modifications by David Rohr, [email protected]
18+
*
19+
*/
20+
21+
#ifndef _GAZEBO_LIFT_DRAG_PLUGIN_HH_
22+
#define _GAZEBO_LIFT_DRAG_PLUGIN_HH_
23+
24+
#include <mutex>
25+
26+
#include <string>
27+
#include <vector>
28+
29+
#include "gazebo/common/Plugin.hh"
30+
#include "gazebo/physics/physics.hh"
31+
#include "gazebo/transport/TransportTypes.hh"
32+
#include <ignition/math.hh>
33+
34+
#include "common.h"
35+
#include "uav_parameters.h"
36+
37+
#include <math.h>
38+
#include <Eigen/Eigen>
39+
#include "gazebo/msgs/msgs.hh"
40+
#include <stdio.h>
41+
#include <boost/bind.hpp>
42+
#include <gazebo/gazebo.hh>
43+
#include <gazebo/common/common.hh>
44+
#include "PropulsionSlipstream.pb.h"
45+
#include "VisVectorArray.pb.h"
46+
#include "WindSpeedBeta.pb.h"
47+
#include "ConnectGazeboToRosTopic.pb.h"
48+
#include <Float32.pb.h>
49+
#include <iostream>
50+
#include <fstream>
51+
52+
#include <algorithm>
53+
54+
#include "gazebo/common/Assert.hh"
55+
#include "gazebo/sensors/SensorManager.hh"
56+
#include "gazebo/transport/transport.hh"
57+
#include <iomanip>
58+
59+
#define AIRFOIL_N_VIS_VEC 6
60+
#define BODY_N_VIS_VEC 2
61+
62+
namespace gazebo
63+
{
64+
65+
typedef ignition::math::Vector3d V3D;
66+
typedef ignition::math::Matrix3<double> M3D;
67+
68+
typedef const boost::shared_ptr<const gz_visualization_msgs::VisVectorArray> GzVisVectorArrayMsgPtr;
69+
typedef const boost::shared_ptr<const gz_mav_msgs::PropulsionSlipstream> PropulsionSlipstreamPtr;
70+
typedef const boost::shared_ptr<const gz_mav_msgs::WindSpeedBeta> WindPtr;
71+
typedef const boost::shared_ptr<const gz_std_msgs::Float32> Float32Ptr;
72+
static const std::string kDefaultPropulsionSlipstreamSubTopic = "/propulsion_slipstream";
73+
static constexpr double kDefaultRhoAir = 1.2041; // air density 1.2041 kg/m³ (dry, @20 °C, 101.325 kPa)
74+
75+
76+
class GazeboAerodynamics : public ModelPlugin
77+
{
78+
/// \brief Constructor.
79+
public:
80+
GazeboAerodynamics():
81+
ModelPlugin(){gzdbg<<"gazebo_aerodynamics constructed"<<std::endl;}
82+
~GazeboAerodynamics();
83+
84+
protected:
85+
void Load(physics::ModelPtr _model, sdf::ElementPtr _sdf);
86+
void OnUpdate();
87+
88+
private:
89+
std::string namespace_;
90+
transport::NodePtr node_handle_;
91+
physics::WorldPtr world;
92+
physics::ModelPtr model;
93+
physics::LinkPtr link;
94+
event::ConnectionPtr updateConnection;
95+
96+
double rho_ = kDefaultRhoAir; // air density 1.2041 kg/m³ (dry, @20 °C, 101.325 kPa)
97+
98+
struct ControlSurface {
99+
ControlSurface():
100+
cs_ref(0.0){}
101+
102+
physics::JointPtr control_joint = nullptr;
103+
transport::SubscriberPtr control_ref_sub = nullptr;
104+
std::string cs_ref_topic;
105+
bool from_topic = false;
106+
std::atomic<double> cs_ref;
107+
V3D control_joint_rad_to_cl = V3D(0,0,0); // dC_L/dCS slope, [1/rad]
108+
V3D control_joint_rad_to_cd = V3D(0,0,0); // dC_D/dCS slope, [1/rad]
109+
V3D control_joint_rad_to_cm = V3D(0,0,0); // dC_M/dCS slope, [1/rad]
110+
double d_aoa_b_d_delta_cs = 0; // dAlpha_break/dCs slope [rad/rad]
111+
void Callback(Float32Ptr& reference){
112+
cs_ref = (double)reference->data();
113+
}
114+
};
115+
116+
struct Wind {
117+
Wind(){}
118+
119+
transport::SubscriberPtr wind_sub_ = nullptr;
120+
std::mutex wind_lock;
121+
std::string wind_topic;
122+
123+
V3D pos_ned = V3D(0,0,0);
124+
V3D wind_ned = V3D(0,0,0);
125+
M3D wind_grad_ned = M3D(0,0,0,0,0,0,0,0,0);
126+
127+
void Callback(WindPtr& wind){
128+
std::unique_lock<std::mutex> lock(wind_lock);
129+
130+
pos_ned = V3D(wind->pos_ned().x(),
131+
wind->pos_ned().y(),
132+
wind->pos_ned().z());
133+
134+
wind_ned = V3D(wind->wind_ned().x(),
135+
wind->wind_ned().y(),
136+
wind->wind_ned().z());
137+
138+
wind_grad_ned = M3D(wind->wind_grad_ned().xx(),
139+
wind->wind_grad_ned().xy(),
140+
wind->wind_grad_ned().xz(),
141+
wind->wind_grad_ned().yx(),
142+
wind->wind_grad_ned().yy(),
143+
wind->wind_grad_ned().yz(),
144+
wind->wind_grad_ned().zx(),
145+
wind->wind_grad_ned().zy(),
146+
wind->wind_grad_ned().zz());
147+
lock.unlock();
148+
}
149+
150+
V3D GetWind(V3D p_cp){
151+
std::unique_lock<std::mutex> lock(wind_lock); //necessary? atomic V3D?
152+
V3D wind_local = wind_ned + wind_grad_ned*(p_cp-pos_ned);
153+
//V3D wind_local = wind_grad_ned*(p_cp-pos_ned);
154+
lock.unlock();
155+
return wind_local;
156+
}
157+
};
158+
159+
struct Slipstream {
160+
Slipstream(){}
161+
162+
transport::SubscriberPtr propulsion_slipstream_sub_ = nullptr;
163+
std::mutex slipstream_lock;
164+
std::string slpstr_topic;
165+
166+
V3D p_rot = V3D(0,0,0);
167+
V3D d_wake = V3D(0,0,0);
168+
V3D d_wake_e = V3D(0,0,0);
169+
V3D v_ind_d = V3D(0,0,0);
170+
V3D v_ind_e = V3D(0,0,0);
171+
172+
double r_rot = 0;
173+
174+
void Callback(PropulsionSlipstreamPtr& propulsion_slipstream){
175+
std::unique_lock<std::mutex> lock(slipstream_lock);
176+
// position of rotordisk center wrt world, expressed in world frame [m]
177+
p_rot = V3D(propulsion_slipstream->rotor_pos().x(),
178+
propulsion_slipstream->rotor_pos().y(),
179+
propulsion_slipstream->rotor_pos().z());
180+
181+
// wake direction expressed in world frame [-]
182+
d_wake = V3D(propulsion_slipstream->wake_dir().x(),
183+
propulsion_slipstream->wake_dir().y(),
184+
propulsion_slipstream->wake_dir().z());
185+
d_wake_e = d_wake.Normalized();
186+
187+
// induced velocity at rotordisk, expressed in world frame [m/s]
188+
v_ind_d = V3D(propulsion_slipstream->ind_vel_disk().x(),
189+
propulsion_slipstream->ind_vel_disk().y(),
190+
propulsion_slipstream->ind_vel_disk().z());
191+
192+
// induced velocity at end of wake (Note: not necessarily 0!)
193+
v_ind_e = V3D(propulsion_slipstream->ind_vel_end().x(),
194+
propulsion_slipstream->ind_vel_end().y(),
195+
propulsion_slipstream->ind_vel_end().z());
196+
197+
// propeller/wake diameter
198+
r_rot = propulsion_slipstream->prop_diam()/2;
199+
lock.unlock();
200+
}
201+
202+
V3D GetIndVel(V3D p_cp){
203+
204+
V3D v_ind; // induced velocity at cp (e.g. due to slipstream)
205+
std::unique_lock<std::mutex> lock(slipstream_lock);
206+
V3D p_r2cp_ = p_cp - p_rot;
207+
double off_a_ = d_wake_e.Dot(p_r2cp_); // axial distance in wake (d1 in report)
208+
double off_p_ = (off_a_*d_wake_e-p_r2cp_).Length(); // radial distance to wake centerline (d2 in report)
209+
210+
211+
if(off_a_>0 && d_wake.Length()>off_a_){
212+
// if in zone of slipstream influence
213+
double k_a_ = (d_wake.Length()-off_a_)/d_wake.Length(); // axial direction interpolation weight
214+
double r_rot_exp = (2-1*k_a_)*r_rot;
215+
double k_p_ = 1-pow((off_p_/r_rot_exp),4);
216+
k_p_ = ignition::math::clamp(k_p_,0.0,1.0); // radial distance downscaling
217+
v_ind = k_p_*(k_a_*v_ind_d+(1-k_a_)*v_ind_e); // induced velocity at airfoil segment cp
218+
}
219+
220+
lock.unlock();
221+
return v_ind;
222+
}
223+
};
224+
225+
struct Segment {
226+
Segment(){}
227+
228+
physics::LinkPtr ref_link = nullptr; // reference link for force/torque calculation
229+
physics::LinkPtr act_link = nullptr; // link to apply force/torque to
230+
231+
// To include hyteresis in future implementation, currently not used
232+
double alpha_prev = 0;
233+
double alpha_dot = 0;
234+
bool cl_hist_up = true;
235+
236+
AerodynamicParameters aero_params;
237+
238+
V3D cp = V3D(0,0,0); // Center of pressure wrt link frame, expressed in link frame
239+
V3D fwd = V3D(1,0,0);
240+
V3D upwd = V3D(0,0,1);
241+
double seg_area;
242+
243+
double seg_chord;
244+
double ellp_mult;
245+
246+
ControlSurface * cs;
247+
int n_cs = 0;
248+
249+
/// \brief Quantities to model propeller/rotor wake/slipstream
250+
251+
Slipstream * slpstr;
252+
V3D v_ind_cp; // induced velocity at cp (e.g. due to slipstream)
253+
int n_slpstr = 0;
254+
255+
Wind * wind;
256+
V3D wind_cp;
257+
int n_wind = 0;
258+
259+
/// \brief For visualization in rviz
260+
std::string vector_vis_array_topic;
261+
gazebo::transport::PublisherPtr vector_vis_array_pub;
262+
gz_visualization_msgs::VisVectorArray vector_vis_array_msg;
263+
std::array<gz_visualization_msgs::ArrowMarker*, AIRFOIL_N_VIS_VEC> vec_vis;
264+
265+
void UpdateIndVel(V3D w_cp) {
266+
v_ind_cp = V3D(0,0,0);
267+
for(int j=0; j<n_slpstr; j++){
268+
v_ind_cp += slpstr[j].GetIndVel(w_cp);
269+
}
270+
}
271+
272+
void UpdateWind(V3D w_cp) {
273+
wind_cp = V3D(0,0,0);
274+
for(int j=0; j<n_wind; j++){
275+
wind_cp += wind[j].GetWind(w_cp);
276+
}
277+
}
278+
279+
};
280+
281+
Segment * segments_;
282+
int n_seg_ = 0;
283+
284+
struct Body {
285+
286+
Body():
287+
a_fus_xx(0),
288+
a_fus_yy(0),
289+
a_fus_zz(0),
290+
cd_cyl_ax(0.82),
291+
cd_cyl_lat(1.17),
292+
cp(0,0,0),
293+
fwd(1,0,0),
294+
upwd(0,0,1){}
295+
296+
physics::LinkPtr ref_link = nullptr; // reference link for force/torque calculation
297+
physics::LinkPtr act_link = nullptr; // link to apply force/torque to
298+
299+
double a_fus_xx; // forward-projected area of fuselage, [m^2]
300+
double a_fus_yy; // side-projected area of fuselage, [m^2]
301+
double a_fus_zz; // down-projected area of fuselage, [m^2]
302+
double cd_cyl_ax; // drag coefficient of long cylinder in axial flow, [-]
303+
double cd_cyl_lat; // drag coefficient of cylinder in lateral flow, [-]
304+
305+
V3D cp;
306+
V3D fwd;
307+
V3D upwd;
308+
309+
Wind * wind;
310+
V3D wind_cp;
311+
int n_wind = 0;
312+
313+
/// \brief For visualization in rviz
314+
std::string vector_vis_array_topic;
315+
gazebo::transport::PublisherPtr vector_vis_array_pub;
316+
gz_visualization_msgs::VisVectorArray vector_vis_array_msg;
317+
std::array<gz_visualization_msgs::ArrowMarker*, BODY_N_VIS_VEC> vec_vis;
318+
319+
void UpdateWind(V3D w_cp) {
320+
wind_cp = V3D(0,0,0);
321+
for(int j=0; j<n_wind; j++){
322+
wind_cp += wind[j].GetWind(w_cp);
323+
}
324+
}
325+
};
326+
327+
Body * bodies_;
328+
int n_bdy_ = 0;
329+
330+
std::string vector_vis_array_topic_;
331+
gz_visualization_msgs::VisVectorArray vector_vis_array_;
332+
gazebo::transport::PublisherPtr vector_vis_array_pub_;
333+
334+
common::Time last_time_;
335+
336+
bool pubs_and_subs_created_ = false;
337+
338+
};
339+
340+
}
341+
#endif

0 commit comments

Comments
 (0)