34 #include <geometry_msgs/WrenchStamped.h> 42 #include <boost/thread/mutex.hpp> 43 #include <std_msgs/Bool.h> 60 attitude_subscriber_helper_.reset();
61 estop_sub_.shutdown();
72 root_nh.
param<std::string>(
"base_link_frame", base_link_frame_,
"base_link");
73 root_nh.
param<std::string>(
"base_stabilized_frame", base_stabilized_frame_,
"base_stabilized");
74 root_nh.
param<
double>(
"estop_deceleration", estop_deceleration_, 1.0);
75 double command_timeout_sec = 0.0;
76 root_nh.
param<
double>(
"command_timeout", command_timeout_sec, 0.0);
81 base_link_frame_ =
tf::resolve(tf_prefix_, base_link_frame_);
82 base_stabilized_frame_ =
tf::resolve(tf_prefix_, base_stabilized_frame_);
92 attitude_subscriber_helper_ = boost::make_shared<AttitudeSubscriberHelper>(
ros::NodeHandle(root_nh,
"command"),
93 boost::ref(command_mutex_),
94 boost::ref(attitude_command_),
95 boost::ref(yawrate_command_),
96 boost::ref(thrust_command_));
103 attitude_limiter_.init(controller_nh);
104 yawrate_limiter_.init(controller_nh,
"yawrate");
116 pid_.yawrate.reset();
117 wrench_control_ = geometry_msgs::WrenchStamped();
123 wrench_output_->start();
128 wrench_output_->stop();
133 boost::mutex::scoped_lock lock(command_mutex_);
135 if (attitude_input_->connected() && attitude_input_->enabled())
137 attitude_command_ = attitude_input_->getCommand();
139 if (yawrate_input_->connected() && yawrate_input_->enabled())
141 yawrate_command_ = yawrate_input_->getCommand();
143 if (thrust_input_->connected() && thrust_input_->enabled())
145 thrust_command_ = thrust_input_->getCommand();
148 attitude_command_ = attitude_limiter_(attitude_command_);
149 yawrate_command_ = yawrate_limiter_(yawrate_command_);
150 thrust_command_ = thrust_limiter_(thrust_command_);
153 if ((motor_status_->motorStatus().running ==
true) &&
154 !command_timeout_.isZero() && (
155 time > attitude_command_.header.stamp + command_timeout_ ||
156 time > yawrate_command_.header.stamp + command_timeout_ ||
157 time > thrust_command_.header.stamp + command_timeout_ ) )
159 if (!command_estop_) {
160 estop_thrust_command_ = thrust_command_;
163 << (time - std::min(std::min(attitude_command_.header.stamp, yawrate_command_.header.stamp), thrust_command_.header.stamp)).toSec() <<
164 "s, triggering estop");
165 command_estop_ =
true;
166 }
else if (command_estop_) {
167 command_estop_ =
false;
170 double roll, pitch, yaw;
171 pose_->getEulerRPY(roll, pitch, yaw);
173 Twist twist = twist_->twist(), twist_body;
174 twist_body.linear = pose_->toBody(twist.linear);
175 twist_body.angular = pose_->toBody(twist.angular);
177 Accel accel = accel_->acceleration(), accel_body;
178 accel_body.linear = pose_->toBody(accel.linear);
179 accel_body.angular = pose_->toBody(accel.angular);
181 if (estop_ || command_estop_)
183 attitude_command_.roll = attitude_command_.pitch = yawrate_command_.turnrate = 0;
184 estop_thrust_command_.thrust -= estop_deceleration_ * mass_ * period.
toSec();
185 if (estop_thrust_command_.thrust < 0) estop_thrust_command_.thrust = 0;
186 thrust_command_ = estop_thrust_command_;
192 Vector3 acceleration_command_base_stabilized;
193 acceleration_command_base_stabilized.x =
sin(attitude_command_.pitch);
194 acceleration_command_base_stabilized.y = -
sin(attitude_command_.roll);
195 acceleration_command_base_stabilized.z = 1.0;
199 double sin_yaw, cos_yaw;
200 sincos(yaw, &sin_yaw, &cos_yaw);
201 Vector3 acceleration_command_world, acceleration_command_body;
202 acceleration_command_world.x = cos_yaw * acceleration_command_base_stabilized.x - sin_yaw * acceleration_command_base_stabilized.y;
203 acceleration_command_world.y = sin_yaw * acceleration_command_base_stabilized.x + cos_yaw * acceleration_command_base_stabilized.y;
204 acceleration_command_world.z = acceleration_command_base_stabilized.z;
205 acceleration_command_body = pose_->toBody(acceleration_command_world);
208 wrench_control_.wrench.torque.x = inertia_[0] * pid_.roll.computeCommand(-acceleration_command_body.y, period);
209 wrench_control_.wrench.torque.y = inertia_[1] * pid_.pitch.computeCommand(acceleration_command_body.x, period);
210 wrench_control_.wrench.torque.z = inertia_[2] * pid_.yawrate.computeCommand((yawrate_command_.turnrate - twist_body.angular.z), period);
211 wrench_control_.wrench.force.x = 0.0;
212 wrench_control_.wrench.force.y = 0.0;
213 wrench_control_.wrench.force.z = thrust_command_.thrust;
216 wrench_control_.header.stamp = time;
217 wrench_control_.header.frame_id = base_link_frame_;
218 wrench_output_->setCommand(wrench_control_.wrench);
221 void estopCb(
const std_msgs::BoolConstPtr &estop_msg)
223 boost::mutex::scoped_lock lock(command_mutex_);
225 bool estop =
static_cast<bool>(estop_msg->data);
226 if (estop_ ==
false && estop ==
true)
228 estop_thrust_command_ = thrust_command_;
virtual void stopping(const ros::Time &time)
virtual void starting(const ros::Time &time)
ros::Subscriber estop_sub_
AttitudeCommandHandlePtr attitude_input_
std::string getPrefixParam(ros::NodeHandle &nh)
hector_quadrotor_interface::YawrateCommandLimiter yawrate_limiter_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
hector_uav_msgs::ThrustCommand thrust_command_
hector_uav_msgs::ThrustCommand estop_thrust_command_
boost::shared_ptr< HandleType > addInput(const std::string &name)
YawrateCommandHandlePtr yawrate_input_
hector_uav_msgs::AttitudeCommand attitude_command_
WrenchCommandHandlePtr wrench_output_
boost::mutex command_mutex_
hector_quadrotor_interface::ThrustCommandLimiter thrust_limiter_
std::string resolve(const std::string &prefix, const std::string &frame_name)
double estop_deceleration_
ThrustCommandHandlePtr thrust_input_
void estopCb(const std_msgs::BoolConstPtr &estop_msg)
virtual ~AttitudeController()
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
TFSIMD_FORCE_INLINE Vector3()
#define ROS_WARN_STREAM_THROTTLE_NAMED(rate, name, args)
boost::shared_ptr< hector_quadrotor_interface::AttitudeSubscriberHelper > attitude_subscriber_helper_
control_toolbox::Pid yawrate
boost::shared_ptr< HandleType > addOutput(const std::string &name)
hector_uav_msgs::YawrateCommand yawrate_command_
geometry_msgs::WrenchStamped wrench_control_
ros::Duration command_timeout_
AccelerationHandlePtr accel_
virtual void update(const ros::Time &time, const ros::Duration &period)
MotorStatusHandlePtr motor_status_
bool getMassAndInertia(const ros::NodeHandle &nh, double &mass, double inertia[3])
MotorStatusHandlePtr getMotorStatus()
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
virtual bool init(hector_quadrotor_interface::QuadrotorInterface *interface, ros::NodeHandle &root_nh, ros::NodeHandle &controller_nh)
std::string base_stabilized_frame_
INLINE Rall1d< T, V, S > sin(const Rall1d< T, V, S > &arg)
AccelerationHandlePtr getAccel()
hector_quadrotor_interface::AttitudeCommandLimiter attitude_limiter_
TwistHandlePtr getTwist()