00001 #include "kinton_vs_control_alg_node.h"
00002
00003 KintonVsControlAlgNode::KintonVsControlAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<KintonVsControlAlgorithm>(),
00005 estop_(false),
00006 serial_(false),
00007 height_fix_(0.0),
00008 time_(0),
00009 time_last_(0)
00010 {
00011
00012 this->loop_rate_ = 100;
00013
00014
00015 this->nm_pid_thrust_.initPid(this->nm_thrust_kp_, 0, this->nm_thrust_kd_, 0, 0);
00016
00017
00018 this->nm_pid_roll_.initPid(this->nm_roll_kp_, 0, this->nm_roll_kd_, 0, 0);
00019
00020
00021 this->nm_pid_pitch_.initPid(this->nm_pitch_kp_, 0, this->nm_pitch_kd_, 0, 0);
00022
00023
00024 this->nm_pid_yaw_.initPid(this->nm_yaw_kp_, 0, this->nm_yaw_kd_, 0, 0);
00025
00026 this->cam_twist_ = Eigen::MatrixXd::Zero(6,1);
00027
00028
00029 tf::TransformListener listener;
00030 tf::StampedTransform tf_quad_to_cam;
00031
00032
00033 sleep(1.0);
00034
00035 try {
00036 listener.waitForTransform("/base_link","/front_cam_optical_frame", ros::Time::now(), ros::Duration(1.0));
00037 listener.lookupTransform("/base_link","/front_cam_optical_frame", ros::Time::now(), tf_quad_to_cam);
00038 }
00039 catch (tf::TransformException ex) {
00040 ROS_ERROR("Quad_to_cam Transform error: %s",ex.what());
00041 }
00042
00043
00044 this->T_quad_to_cam_ = getTransform(tf_quad_to_cam);
00045
00046
00047 this->cmd_yaw_publisher_ = this->public_node_handle_.advertise<std_msgs::Float64>("cmd_yaw", 10);
00048 this->cmd_pitch_publisher_ = this->public_node_handle_.advertise<std_msgs::Float64>("cmd_pitch", 10);
00049 this->cmd_roll_publisher_ = this->public_node_handle_.advertise<std_msgs::Float64>("cmd_roll", 10);
00050 this->cmd_thrust_publisher_ = this->public_node_handle_.advertise<std_msgs::Float64>("cmd_thrust", 10);
00051 this->ESTOP_publisher_ = this->public_node_handle_.advertise<std_msgs::Bool>("ESTOP", 1);
00052
00053
00054 this->cam_vel_subscriber_ = this->public_node_handle_.subscribe("cam_vel", 100, &KintonVsControlAlgNode::cam_vel_callback, this);
00055 this->odom_subscriber_ = this->public_node_handle_.subscribe("odom", 100, &KintonVsControlAlgNode::odom_callback, this);
00056 this->ll_status_subscriber_ = this->public_node_handle_.subscribe("ll_status", 100, &KintonVsControlAlgNode::ll_status_callback, this);
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 }
00067
00068 KintonVsControlAlgNode::~KintonVsControlAlgNode(void)
00069 {
00070
00071 }
00072
00073 void KintonVsControlAlgNode::mainNodeThread(void)
00074 {
00075
00076
00077
00078
00079
00080
00081 this->time_ = ros::Time::now();
00082
00083 this->cam_vel_mutex_.enter();
00084 bool marker_ctrl = this->marker_ctrl_;
00085 this->cam_vel_mutex_.exit();
00086
00087
00088 Eigen::MatrixXd cmd_raw = Eigen::MatrixXd::Zero(4,1);
00089 Eigen::MatrixXd quad_cmd = Eigen::MatrixXd::Zero(4,1);
00090 if (marker_ctrl){
00091
00092
00093 Eigen::MatrixXd quad_vel;
00094 quad_vel = cam_to_quad_vel();
00095
00096 cmd_raw(0,0) = quad_vel(0,0);
00097 cmd_raw(1,0) = quad_vel(1,0);
00098 cmd_raw(2,0) = quad_vel(5,0);
00099 cmd_raw(3,0) = quad_vel(2,0);
00100 }
00101 else{
00102 this->odom_mutex_.enter();
00103 double height = this->height_;
00104 double height_fix = this->height_fix_;
00105 this->odom_mutex_.exit();
00106
00107
00108 Eigen::MatrixXd error_no_marker = Eigen::MatrixXd::Zero(4,1);
00109 error_no_marker(2,0) = height - height_fix;
00110
00111
00112
00113 cmd_raw(0,0) = this->nm_pid_roll_.updatePid(error_no_marker(0,0), this->time_ - this->time_last_);
00114 cmd_raw(1,0) = this->nm_pid_pitch_.updatePid(error_no_marker(1,0), this->time_ - this->time_last_);
00115 cmd_raw(2,0) = this->nm_pid_yaw_.updatePid(error_no_marker(2,0), this->time_ - this->time_last_);
00116 cmd_raw(3,0) = this->nm_pid_thrust_.updatePid(error_no_marker(3,0), this->time_ - this->time_last_);
00117 }
00118
00119
00120
00121 quad_cmd = signal_adapt(cmd_raw);
00122
00123
00124 this->cmd_roll_msg_.data = quad_cmd(0,0);
00125 this->cmd_pitch_msg_.data = quad_cmd(1,0);
00126 this->cmd_yaw_msg_.data = quad_cmd(2,0);
00127 this->cmd_thrust_msg_.data = quad_cmd(3,0);
00128
00129 this->cmd_roll_publisher_.publish(this->cmd_roll_msg_);
00130 this->cmd_pitch_publisher_.publish(this->cmd_pitch_msg_);
00131 this->cmd_yaw_publisher_.publish(this->cmd_yaw_msg_);
00132 this->cmd_thrust_publisher_.publish(this->cmd_thrust_msg_);
00133
00134
00135 this->Bool_msg_.data=this->estop_;
00136 if (this->estop_) {
00137 ROS_ERROR_STREAM("EMERGENCY_STOP ENABLED");
00138 this->ESTOP_publisher_.publish(this->Bool_msg_);
00139 }
00140
00141 this->time_last_ = this->time_;
00142 }
00143
00144
00145 void KintonVsControlAlgNode::cam_vel_callback(const geometry_msgs::TwistWithCovariance::ConstPtr& msg)
00146 {
00147
00148
00149
00150
00151 this->cam_vel_mutex_.enter();
00152
00153 if (msg->covariance[0]<1000)
00154 {
00155 this->height_fix_ = this->height_;
00156 this->marker_ctrl_ = true;
00157 }
00158 else{
00159 this->marker_ctrl_ = false;
00160 }
00161
00162
00163 this->cam_twist_(0,0) = msg->twist.linear.x;
00164 this->cam_twist_(1,0) = msg->twist.linear.y;
00165 this->cam_twist_(2,0) = msg->twist.linear.z;
00166 this->cam_twist_(3,0) = msg->twist.angular.x;
00167 this->cam_twist_(4,0) = msg->twist.angular.y;
00168 this->cam_twist_(5,0) = msg->twist.angular.z;
00169
00170
00171
00172
00173
00174 this->cam_vel_mutex_.exit();
00175 }
00176 void KintonVsControlAlgNode::odom_callback(const nav_msgs::Odometry::ConstPtr& msg)
00177 {
00178
00179
00180
00181
00182 this->odom_mutex_.enter();
00183
00184
00185
00186 this->height_ = msg->pose.pose.position.z;
00187
00188
00189
00190 this->odom_mutex_.exit();
00191 }
00192 void KintonVsControlAlgNode::ll_status_callback(const asctec_msgs::LLStatus::ConstPtr& msg)
00193 {
00194
00195
00196
00197
00198 this->ll_status_mutex_.enter();
00199
00200
00201 int ll_status;
00202 ll_status=(int)msg->flightMode;
00203
00204 std::bitset<32> flight_mode;
00205 flight_mode.reset();
00206
00207
00208 int *y,x;
00209 y = reinterpret_cast<int*>(&ll_status);
00210 x=*y;
00211 for(short i=0;i<32;++i) {
00212 flight_mode[i] = x%2;
00213 x /= 2;
00214 }
00215
00216
00217 if ((ll_status|0b1111111101111111)!=0b1111111111111111) ROS_DEBUG("NO Emergency");
00218 if ((ll_status|0b1111111111111101)!=0b1111111111111111) ROS_DEBUG("NO Height Control");
00219 if ((ll_status|0b1111111111111011)!=0b1111111111111111) ROS_DEBUG("NO GPS Mode");
00220 if ((ll_status|0b1111111111011111)!=0b1111111111111111) {
00221 ROS_DEBUG("NO Serial Enable");
00222 this->serial_=false;
00223 this->height_fix_=0;
00224 }
00225 else {
00226 this->serial_=true;
00227 }
00228
00229 if ((ll_status|0b1111111110111111)!=0b1111111111111111) ROS_DEBUG("NO Serial Active");
00230
00231
00232
00233 this->ll_status_mutex_.exit();
00234 }
00235
00236
00237
00238
00239
00240
00241
00242 Eigen::MatrixXd KintonVsControlAlgNode::cam_to_quad_vel()
00243 {
00244
00245 Eigen::MatrixXd cam_lin = Eigen::MatrixXd::Zero(3,1);
00246 Eigen::MatrixXd cam_ang = Eigen::MatrixXd::Zero(3,1);
00247
00248
00249 this->cam_vel_mutex_.enter();
00250 cam_lin = this->cam_twist_.block(0,0,3,1);
00251 cam_ang = this->cam_twist_.block(3,0,3,1);
00252 this->cam_vel_mutex_.exit();
00253
00254
00255
00256 Eigen::MatrixXd quad_ang = Eigen::MatrixXd::Zero(3,1);
00257 quad_ang = this->T_quad_to_cam_.block(0,0,3,3) * cam_ang;
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 Eigen::MatrixXd quad_lin = Eigen::MatrixXd::Zero(3,1);
00278 quad_lin = this->T_quad_to_cam_.block(0,0,3,3) * cam_lin;
00279
00280
00281 Eigen::MatrixXd quad_vel = Eigen::MatrixXd::Zero(6,1);
00282 quad_vel.block(0,0,3,1) = quad_lin;
00283 quad_vel.block(3,0,3,1) = quad_ang;
00284
00285 return quad_vel;
00286 }
00287
00288 Eigen::Matrix4d KintonVsControlAlgNode::getTransform(const tf::StampedTransform& transform)
00289 {
00290
00291 double roll,pitch,yaw;
00292 tf::Quaternion q = transform.getRotation();
00293 tf::Matrix3x3(q).getRPY(roll,pitch,yaw);
00294
00295 Eigen::Matrix3d Rot;
00296 Rot = Eigen::AngleAxisd(yaw, Eigen::Vector3d::UnitZ()) \
00297 * Eigen::AngleAxisd(pitch, Eigen::Vector3d::UnitY()) \
00298 * Eigen::AngleAxisd(roll, Eigen::Vector3d::UnitX());
00299 Eigen::Matrix4d T = Eigen::Matrix4d::Zero();
00300
00301 T.block(0,0,3,3) = Rot;
00302 T(0,3) = transform.getOrigin().x();
00303 T(1,3) = transform.getOrigin().y();
00304 T(2,3) = transform.getOrigin().z();
00305 T(3,3) = 1.0;
00306
00307
00308
00309 return T;
00310 }
00311
00312 Eigen::MatrixXd KintonVsControlAlgNode::signal_adapt(const Eigen::MatrixXd& cmd_raw)
00313 {
00314
00315 Eigen::MatrixXd cmd = Eigen::MatrixXd::Zero(4,1);
00316
00317
00318 cmd(0,0) = cmd_raw(0,0)-this->trimm_y_;
00319 if (cmd(0,0) > this->rollpitch_sat_max_) cmd(0,0) = this->rollpitch_sat_max_;
00320 if (cmd(0,0) < this->rollpitch_sat_min_) cmd(0,0) = this->rollpitch_sat_min_;
00321
00322
00323 cmd(1,0) = cmd_raw(1,0)-this->trimm_x_;
00324 if (cmd(1,0) > this->rollpitch_sat_max_) cmd(1,0) = this->rollpitch_sat_max_;
00325 if (cmd(1,0) < this->rollpitch_sat_min_) cmd(1,0) = this->rollpitch_sat_min_;
00326
00327
00328 cmd(2,0) = cmd_raw(2,0);
00329 if (cmd(2,0) > yaw_sat_max_) cmd(2,0) = this->yaw_sat_max_;
00330 if (cmd(2,0) < yaw_sat_min_) cmd(2,0) = this->yaw_sat_min_;
00331
00332
00333 cmd(3,0) = cmd_raw(3,0) + this->ctrl_ref_;
00334 if (cmd(3,0) > this->sat_max_) cmd(3,0) = this->sat_max_;
00335 if (cmd(3,0) < this->sat_min_) cmd(3,0) = this->sat_min_;
00336
00337 return cmd;
00338 }
00339
00340 void KintonVsControlAlgNode::node_config_update(Config &config, uint32_t level)
00341 {
00342 this->alg_.lock();
00343
00344
00345 this->trimm_x_ = config.trimm_x;
00346 this->trimm_y_ = config.trimm_y;
00347 this->rollpitch_sat_min_ = config.rollpitch_sat_min;
00348 this->rollpitch_sat_max_ = config.rollpitch_sat_max;
00349 this->yaw_sat_min_ = config.yaw_sat_min;
00350 this->yaw_sat_max_ =config.yaw_sat_max;
00351 this->ctrl_ref_ = config.thrust_ctrl_ref;
00352 this->sat_min_ = config.thrust_sat_min;
00353 this->sat_max_ = config.thrust_sat_max;
00354
00355
00356 this->nm_roll_kp_ = config.nm_roll_kp;
00357 this->nm_roll_kd_ = config.nm_roll_kd;
00358 this->nm_pitch_kp_ = config.nm_pitch_kp;
00359 this->nm_pitch_kd_ = config.nm_pitch_kd;
00360 this->nm_yaw_kp_ = config.nm_yaw_kp;
00361 this->nm_yaw_kd_ = config.nm_yaw_kd;
00362 this->nm_thrust_kp_ = config.nm_thrust_kp;
00363 this->nm_thrust_kd_ = config.nm_thrust_kd;
00364
00365
00366 this->estop_=config.EMERGENCY_STOP;
00367 this->alg_.unlock();
00368 }
00369
00370 void KintonVsControlAlgNode::addNodeDiagnostics(void)
00371 {
00372 }
00373
00374
00375 int main(int argc,char *argv[])
00376 {
00377 return algorithm_base::main<KintonVsControlAlgNode>(argc, argv, "kinton_vs_control_alg_node");
00378 }