33 #include <boost/array.hpp> 40 #include <boost/array.hpp> 41 #include <Eigen/Geometry> 65 boost::array<real_T,6>
u;
66 boost::array<real_T,6>
y;
108 real_T absoluteAngularVelocity;
111 for (i = 0; i < 6; i++) {
125 y[0] = parameter.
C_wxy * absoluteVelocity * uin[0];
126 y[1] = parameter.
C_wxy * absoluteVelocity * uin[1];
127 y[2] = parameter.
C_wz * absoluteVelocity * uin[2];
130 y[3] = parameter.
C_mxy * absoluteAngularVelocity * uin[3];
131 y[4] = parameter.
C_mxy * absoluteAngularVelocity * uin[4];
132 y[5] = parameter.
C_mz * absoluteAngularVelocity * uin[5];
145 if (!param.
getParam(
"C_wxy", drag_model_->parameters_.C_wxy))
return false;
146 if (!param.
getParam(
"C_wz", drag_model_->parameters_.C_wz))
return false;
147 if (!param.
getParam(
"C_mxy", drag_model_->parameters_.C_mxy))
return false;
148 if (!param.
getParam(
"C_mz", drag_model_->parameters_.C_mz))
return false;
151 std::cout <<
"Loaded the following quadrotor drag model parameters from namespace " << param.
getNamespace() <<
":" << std::endl;
152 std::cout <<
"C_wxy = " << drag_model_->parameters_.C_wxy << std::endl;
153 std::cout <<
"C_wz = " << drag_model_->parameters_.C_wz << std::endl;
154 std::cout <<
"C_mxy = " << drag_model_->parameters_.C_mxy << std::endl;
155 std::cout <<
"C_mz = " << drag_model_->parameters_.C_mz << std::endl;
164 boost::mutex::scoped_lock lock(mutex_);
165 drag_model_->u.assign(0.0);
166 drag_model_->y.assign(0.0);
168 twist_ = geometry_msgs::Twist();
169 wind_ = geometry_msgs::Vector3();
170 wrench_ = geometry_msgs::Wrench();
175 boost::mutex::scoped_lock lock(mutex_);
176 orientation_ = orientation;
181 boost::mutex::scoped_lock lock(mutex_);
187 boost::mutex::scoped_lock lock(mutex_);
188 Eigen::Quaterniond orientation(orientation_.w, orientation_.x, orientation_.y, orientation_.z);
189 Eigen::Matrix<double,3,3> inverse_rotation_matrix(orientation.inverse().toRotationMatrix());
191 Eigen::Vector3d body_linear(body_twist.linear.x, body_twist.linear.y, body_twist.linear.z);
192 Eigen::Vector3d world_linear(inverse_rotation_matrix * body_linear);
193 twist_.linear.x = world_linear.x();
194 twist_.linear.y = world_linear.y();
195 twist_.linear.z = world_linear.z();
197 Eigen::Vector3d body_angular(body_twist.angular.x, body_twist.angular.y, body_twist.angular.z);
198 Eigen::Vector3d world_angular(inverse_rotation_matrix * body_angular);
199 twist_.angular.x = world_angular.x();
200 twist_.angular.y = world_angular.y();
201 twist_.angular.z = world_angular.z();
206 boost::mutex::scoped_lock lock(mutex_);
212 if (dt <= 0.0)
return;
213 boost::mutex::scoped_lock lock(mutex_);
216 drag_model_->u[0] = (twist_.linear.x - wind_.x);
217 drag_model_->u[1] = -(twist_.linear.y - wind_.y);
218 drag_model_->u[2] = -(twist_.linear.z - wind_.z);
219 drag_model_->u[3] = twist_.angular.x;
220 drag_model_->u[4] = -twist_.angular.y;
221 drag_model_->u[5] = -twist_.angular.z;
225 limit(drag_model_->u, -100.0, 100.0);
228 Eigen::Quaterniond orientation(orientation_.w, orientation_.x, orientation_.y, orientation_.z);
229 Eigen::Matrix<double,3,3> rotation_matrix(orientation.toRotationMatrix());
230 Eigen::Map<Eigen::Vector3d> linear(&(drag_model_->u[0]));
231 Eigen::Map<Eigen::Vector3d> angular(&(drag_model_->u[3]));
232 linear = rotation_matrix * linear;
233 angular = rotation_matrix * angular;
236 checknan(drag_model_->u,
"drag model input");
239 f(drag_model_->u.data(), dt, drag_model_->y.data());
242 ROS_DEBUG_STREAM_NAMED(
"quadrotor_aerodynamics",
"aerodynamics.torque: " <<
PrintVector<double>(drag_model_->y.begin() + 3, drag_model_->y.begin() + 6));
243 checknan(drag_model_->y,
"drag model output");
246 wrench_.force.x = -( drag_model_->y[0]);
247 wrench_.force.y = -(-drag_model_->y[1]);
248 wrench_.force.z = -(-drag_model_->y[2]);
249 wrench_.torque.x = -( drag_model_->y[3]);
250 wrench_.torque.y = -(-drag_model_->y[4]);
251 wrench_.torque.z = -(-drag_model_->y[5]);
#define ROS_DEBUG_STREAM_NAMED(name, args)
void setWind(const geometry_msgs::Vector3 &wind)
boost::array< real_T, 6 > y
void f(const double uin[6], double dt, double y[6]) const
void quadrotorDrag(const real_T uin[6], const DragParameters parameter, real_T dt, real_T y[6])
void setOrientation(const geometry_msgs::Quaternion &orientation)
void setTwist(const geometry_msgs::Twist &twist)
boost::array< real_T, 6 > u
static real_T rt_powd_snf(real_T u0, real_T u1)
DragParameters parameters_
bool configure(const ros::NodeHandle ¶m=ros::NodeHandle("~"))
const std::string & getNamespace() const
void limit(T &value, const T &min, const T &max)
static void checknan(T &value, const std::string &text="")
bool getParam(const std::string &key, std::string &s) const
void setBodyTwist(const geometry_msgs::Twist &twist)