sys_status.cpp
Go to the documentation of this file.
00001 
00009 /*
00010  * Copyright 2013 Vladimir Ermakov.
00011  *
00012  * This program is free software; you can redistribute it and/or modify
00013  * it under the terms of the GNU General Public License as published by
00014  * the Free Software Foundation; either version 3 of the License, or
00015  * (at your option) any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful, but
00018  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00019  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00020  * for more details.
00021  *
00022  * You should have received a copy of the GNU General Public License along
00023  * with this program; if not, write to the Free Software Foundation, Inc.,
00024  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00025  */
00026 
00027 #include <mavros/mavros_plugin.h>
00028 #include <pluginlib/class_list_macros.h>
00029 
00030 #include <mavros/State.h>
00031 #include <mavros/BatteryStatus.h>
00032 #include <mavros/StreamRate.h>
00033 #include <mavros/SetMode.h>
00034 
00035 namespace mavplugin {
00036 
00042 class HeartbeatStatus : public diagnostic_updater::DiagnosticTask
00043 {
00044 public:
00045         HeartbeatStatus(const std::string name, size_t win_size) :
00046                 diagnostic_updater::DiagnosticTask(name),
00047                 window_size_(win_size),
00048                 min_freq_(0.2),
00049                 max_freq_(100),
00050                 tolerance_(0.1),
00051                 times_(win_size),
00052                 seq_nums_(win_size),
00053                 last_hb{}
00054         {
00055                 clear();
00056         }
00057 
00058         void clear() {
00059                 lock_guard lock(mutex);
00060                 ros::Time curtime = ros::Time::now();
00061                 count_ = 0;
00062 
00063                 for (int i = 0; i < window_size_; i++)
00064                 {
00065                         times_[i] = curtime;
00066                         seq_nums_[i] = count_;
00067                 }
00068 
00069                 hist_indx_ = 0;
00070         }
00071 
00072         void tick(mavlink_heartbeat_t &hb_struct) {
00073                 lock_guard lock(mutex);
00074                 count_++;
00075                 last_hb = hb_struct;
00076         }
00077 
00078         void run(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00079                 lock_guard lock(mutex);
00080                 ros::Time curtime = ros::Time::now();
00081                 int curseq = count_;
00082                 int events = curseq - seq_nums_[hist_indx_];
00083                 double window = (curtime - times_[hist_indx_]).toSec();
00084                 double freq = events / window;
00085                 seq_nums_[hist_indx_] = curseq;
00086                 times_[hist_indx_] = curtime;
00087                 hist_indx_ = (hist_indx_ + 1) % window_size_;
00088 
00089                 if (events == 0) {
00090                         stat.summary(2, "No events recorded.");
00091                 }
00092                 else if (freq < min_freq_ * (1 - tolerance_)) {
00093                         stat.summary(1, "Frequency too low.");
00094                 }
00095                 else if (freq > max_freq_ * (1 + tolerance_)) {
00096                         stat.summary(1, "Frequency too high.");
00097                 }
00098                 else {
00099                         stat.summary(0, "Normal");
00100                 }
00101 
00102                 stat.addf("Events in window", "%d", events);
00103                 stat.addf("Events since startup", "%d", count_);
00104                 stat.addf("Duration of window (s)", "%f", window);
00105                 stat.addf("Actual frequency (Hz)", "%f", freq);
00106                 stat.addf("MAV Type", "%u", last_hb.type);
00107                 stat.addf("Autopilot type", "%u", last_hb.autopilot);
00108                 stat.addf("Autopilot base mode", "0x%02X", last_hb.base_mode);
00109                 stat.addf("Autopilot custom mode", "0x%08X", last_hb.custom_mode);
00110                 stat.addf("Autopilot system status", "%u", last_hb.system_status);
00111         }
00112 
00113 private:
00114         int count_;
00115         std::vector<ros::Time> times_;
00116         std::vector<int> seq_nums_;
00117         int hist_indx_;
00118         std::recursive_mutex mutex;
00119         const size_t window_size_;
00120         const double min_freq_;
00121         const double max_freq_;
00122         const double tolerance_;
00123         mavlink_heartbeat_t last_hb;
00124 };
00125 
00126 
00127 class SystemStatusDiag : public diagnostic_updater::DiagnosticTask
00128 {
00129 public:
00130         SystemStatusDiag(const std::string name) :
00131                 diagnostic_updater::DiagnosticTask(name),
00132                 last_st{}
00133         { };
00134 
00135         void set(mavlink_sys_status_t &st) {
00136                 lock_guard lock(mutex);
00137                 last_st = st;
00138         }
00139 
00140         void run(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00141                 lock_guard lock(mutex);
00142 
00143                 if ((last_st.onboard_control_sensors_health & last_st.onboard_control_sensors_enabled)
00144                                 != last_st.onboard_control_sensors_enabled)
00145                         stat.summary(2, "Sensor helth");
00146                 else
00147                         stat.summary(0, "Normal");
00148 
00149                 stat.addf("Sensor present", "0x%08X", last_st.onboard_control_sensors_present);
00150                 stat.addf("Sensor enabled", "0x%08X", last_st.onboard_control_sensors_enabled);
00151                 stat.addf("Sensor helth", "0x%08X", last_st.onboard_control_sensors_health);
00152 
00153                 // decode sensor health mask
00154 #define STAT_ADD_SENSOR(msg, sensor_mask)       \
00155                 if (last_st.onboard_control_sensors_enabled & sensor_mask)      \
00156                         stat.add(msg, (last_st.onboard_control_sensors_health & sensor_mask)? "Ok" : "Fail")
00157 
00158                 STAT_ADD_SENSOR("Sensor 3D Gyro", MAV_SYS_STATUS_SENSOR_3D_GYRO);
00159                 STAT_ADD_SENSOR("Sensor 3D Accel", MAV_SYS_STATUS_SENSOR_3D_ACCEL);
00160                 STAT_ADD_SENSOR("Sensor 3D Mag", MAV_SYS_STATUS_SENSOR_3D_MAG);
00161                 STAT_ADD_SENSOR("Sensor Abs Pressure", MAV_SYS_STATUS_SENSOR_ABSOLUTE_PRESSURE);
00162                 STAT_ADD_SENSOR("Sensor Diff Pressure", MAV_SYS_STATUS_SENSOR_DIFFERENTIAL_PRESSURE);
00163                 STAT_ADD_SENSOR("Sensor GPS", MAV_SYS_STATUS_SENSOR_GPS);
00164                 STAT_ADD_SENSOR("Sensor Optical Flow", MAV_SYS_STATUS_SENSOR_OPTICAL_FLOW);
00165                 STAT_ADD_SENSOR("Sensor Vision Position", MAV_SYS_STATUS_SENSOR_VISION_POSITION);
00166                 STAT_ADD_SENSOR("Sensor Laser Position", MAV_SYS_STATUS_SENSOR_LASER_POSITION);
00167                 STAT_ADD_SENSOR("Sensor Ext Grount Truth", MAV_SYS_STATUS_SENSOR_EXTERNAL_GROUND_TRUTH);
00168                 STAT_ADD_SENSOR("Sensor Ang Rate Control", MAV_SYS_STATUS_SENSOR_ANGULAR_RATE_CONTROL);
00169                 STAT_ADD_SENSOR("Sensor Attitude Stab", MAV_SYS_STATUS_SENSOR_ATTITUDE_STABILIZATION);
00170                 STAT_ADD_SENSOR("Sensor Yaw Position", MAV_SYS_STATUS_SENSOR_YAW_POSITION);
00171                 STAT_ADD_SENSOR("Sensor Z/Alt Control", MAV_SYS_STATUS_SENSOR_Z_ALTITUDE_CONTROL);
00172                 STAT_ADD_SENSOR("Sensor X/Y Pos Control", MAV_SYS_STATUS_SENSOR_XY_POSITION_CONTROL);
00173                 STAT_ADD_SENSOR("Sensor Motor Outputs", MAV_SYS_STATUS_SENSOR_MOTOR_OUTPUTS);
00174                 STAT_ADD_SENSOR("Sensor RC Receiver", MAV_SYS_STATUS_SENSOR_RC_RECEIVER);
00175                 STAT_ADD_SENSOR("Sensor 3D Gyro 2", MAV_SYS_STATUS_SENSOR_3D_GYRO2);
00176                 STAT_ADD_SENSOR("Sensor 3D Accel 2", MAV_SYS_STATUS_SENSOR_3D_ACCEL2);
00177                 STAT_ADD_SENSOR("Sensor 3D Mag 2", MAV_SYS_STATUS_SENSOR_3D_MAG2);
00178                 STAT_ADD_SENSOR("Geofence health", MAV_SYS_STATUS_GEOFENCE);
00179                 STAT_ADD_SENSOR("AHRS health", MAV_SYS_STATUS_AHRS);
00180                 //STAT_ADD_SENSOR("Terrain health", MAV_SYS_STATUS_TERRAIN);
00181 
00182 #undef STAT_ADD_SENSOR
00183 
00184                 stat.addf("CPU Load (%)", "%.1f", last_st.load / 10.0);
00185                 stat.addf("Drop rate (%)", "%.1f", last_st.drop_rate_comm / 10.0);
00186                 stat.addf("Errors comm", "%d", last_st.errors_comm);
00187                 stat.addf("Errors count #1", "%d", last_st.errors_count1);
00188                 stat.addf("Errors count #2", "%d", last_st.errors_count2);
00189                 stat.addf("Errors count #3", "%d", last_st.errors_count3);
00190                 stat.addf("Errors count #4", "%d", last_st.errors_count4);
00191         }
00192 
00193 private:
00194         std::recursive_mutex mutex;
00195         mavlink_sys_status_t last_st;
00196 };
00197 
00198 
00199 class BatteryStatusDiag : public diagnostic_updater::DiagnosticTask
00200 {
00201 public:
00202         BatteryStatusDiag(const std::string name) :
00203                 diagnostic_updater::DiagnosticTask(name),
00204                 voltage(-1.0),
00205                 current(0.0),
00206                 remaining(0.0),
00207                 min_voltage(6)
00208         {};
00209 
00210         void set_min_voltage(float volt) {
00211                 lock_guard lock(mutex);
00212                 min_voltage = volt;
00213         }
00214 
00215         void set(float volt, float curr, float rem) {
00216                 lock_guard lock(mutex);
00217                 voltage = volt;
00218                 current = curr;
00219                 remaining = rem;
00220         }
00221 
00222         void run(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00223                 lock_guard lock(mutex);
00224 
00225                 if (voltage < 0)
00226                         stat.summary(2, "No data");
00227                 else if (voltage < min_voltage)
00228                         stat.summary(1, "Low voltage");
00229                 else
00230                         stat.summary(0, "Normal");
00231 
00232                 stat.addf("Voltage", "%.2f", voltage);
00233                 stat.addf("Current", "%.1f", current);
00234                 stat.addf("Remaining", "%.1f", remaining * 100);
00235         }
00236 
00237 private:
00238         std::recursive_mutex mutex;
00239         float voltage;
00240         float current;
00241         float remaining;
00242         float min_voltage;
00243 };
00244 
00245 
00246 class MemInfo : public diagnostic_updater::DiagnosticTask
00247 {
00248 public:
00249         MemInfo(const std::string name) :
00250                 diagnostic_updater::DiagnosticTask(name),
00251                 freemem(-1),
00252                 brkval(0)
00253         {};
00254 
00255         void set(uint16_t f, uint16_t b) {
00256                 lock_guard lock(mutex);
00257                 freemem = f;
00258                 brkval = b;
00259         }
00260 
00261         void run(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00262                 lock_guard lock(mutex);
00263 
00264                 if (freemem < 0)
00265                         stat.summary(2, "No data");
00266                 else if (freemem < 200)
00267                         stat.summary(1, "Low mem");
00268                 else
00269                         stat.summary(0, "Normal");
00270 
00271                 stat.addf("Free memory (B)", "%zd", freemem);
00272                 stat.addf("Heap top", "0x%04X", brkval);
00273         }
00274 
00275 private:
00276         std::recursive_mutex mutex;
00277         ssize_t freemem;
00278         uint16_t brkval;
00279 };
00280 
00281 
00282 class HwStatus : public diagnostic_updater::DiagnosticTask
00283 {
00284 public:
00285         HwStatus(const std::string name) :
00286                 diagnostic_updater::DiagnosticTask(name),
00287                 vcc(-1.0),
00288                 i2cerr(0),
00289                 i2cerr_last(0)
00290         {};
00291 
00292         void set(uint16_t v, uint8_t e) {
00293                 lock_guard lock(mutex);
00294                 vcc = v / 1000.0;
00295                 i2cerr = e;
00296         }
00297 
00298         void run(diagnostic_updater::DiagnosticStatusWrapper &stat) {
00299                 lock_guard lock(mutex);
00300 
00301                 if (vcc < 0)
00302                         stat.summary(2, "No data");
00303                 else if (vcc < 4.5)
00304                         stat.summary(1, "Low voltage");
00305                 else if (i2cerr != i2cerr_last) {
00306                         i2cerr_last = i2cerr;
00307                         stat.summary(1, "New I2C error");
00308                 }
00309                 else
00310                         stat.summary(0, "Normal");
00311 
00312                 stat.addf("Core voltage", "%f", vcc);
00313                 stat.addf("I2C errors", "%zu", i2cerr);
00314         }
00315 
00316 private:
00317         std::recursive_mutex mutex;
00318         float vcc;
00319         size_t i2cerr;
00320         size_t i2cerr_last;
00321 };
00322 
00323 
00328 class SystemStatusPlugin : public MavRosPlugin
00329 {
00330 public:
00331         SystemStatusPlugin() :
00332                 uas(nullptr),
00333                 hb_diag("Heartbeat", 10),
00334                 mem_diag("APM Memory"),
00335                 hwst_diag("APM Hardware"),
00336                 sys_diag("System"),
00337                 batt_diag("Battery")
00338         {};
00339 
00340         void initialize(UAS &uas_,
00341                         ros::NodeHandle &nh,
00342                         diagnostic_updater::Updater &diag_updater)
00343         {
00344                 uas = &uas_;
00345 
00346                 double conn_timeout_d;
00347                 double conn_heartbeat_d;
00348                 double min_voltage;
00349                 bool disable_diag;
00350 
00351                 nh.param("conn_timeout", conn_timeout_d, 30.0);
00352                 nh.param("conn_heartbeat", conn_heartbeat_d, 0.0);
00353                 nh.param("sys/min_voltage", min_voltage, 6.0);
00354                 nh.param("sys/disable_diag", disable_diag, false);
00355 
00356                 // heartbeat diag always enabled
00357                 diag_updater.add(hb_diag);
00358                 if (!disable_diag) {
00359                         diag_updater.add(sys_diag);
00360                         diag_updater.add(batt_diag);
00361 #ifdef MAVLINK_MSG_ID_MEMINFO
00362                         diag_updater.add(mem_diag);
00363 #endif
00364 #ifdef MAVLINK_MSG_ID_HWSTATUS
00365                         diag_updater.add(hwst_diag);
00366 #endif
00367 
00368                         batt_diag.set_min_voltage(min_voltage);
00369                 }
00370 
00371 
00372                 // one-shot timeout timer
00373                 timeout_timer = nh.createTimer(ros::Duration(conn_timeout_d),
00374                                 &SystemStatusPlugin::timeout_cb, this, true);
00375                 timeout_timer.start();
00376 
00377                 if (conn_heartbeat_d > 0.0) {
00378                         heartbeat_timer = nh.createTimer(ros::Duration(conn_heartbeat_d),
00379                                         &SystemStatusPlugin::heartbeat_cb, this);
00380                         heartbeat_timer.start();
00381                 }
00382 
00383                 state_pub = nh.advertise<mavros::State>("state", 10);
00384                 batt_pub = nh.advertise<mavros::BatteryStatus>("battery", 10);
00385                 rate_srv = nh.advertiseService("set_stream_rate", &SystemStatusPlugin::set_rate_cb, this);
00386                 mode_srv = nh.advertiseService("set_mode", &SystemStatusPlugin::set_mode_cb, this);
00387         }
00388 
00389         const std::string get_name() const {
00390                 return "SystemStatus";
00391         }
00392 
00393         const message_map get_rx_handlers() {
00394                 return {
00395                         MESSAGE_HANDLER(MAVLINK_MSG_ID_HEARTBEAT, &SystemStatusPlugin::handle_heartbeat),
00396                         MESSAGE_HANDLER(MAVLINK_MSG_ID_SYS_STATUS, &SystemStatusPlugin::handle_sys_status),
00397                         MESSAGE_HANDLER(MAVLINK_MSG_ID_STATUSTEXT, &SystemStatusPlugin::handle_statustext),
00398 #ifdef MAVLINK_MSG_ID_MEMINFO
00399                         MESSAGE_HANDLER(MAVLINK_MSG_ID_MEMINFO, &SystemStatusPlugin::handle_meminfo),
00400 #endif
00401 #ifdef MAVLINK_MSG_ID_HWSTATUS
00402                         MESSAGE_HANDLER(MAVLINK_MSG_ID_HWSTATUS, &SystemStatusPlugin::handle_hwstatus),
00403 #endif
00404                 };
00405         }
00406 
00407 private:
00408         UAS *uas;
00409         HeartbeatStatus hb_diag;
00410         MemInfo mem_diag;
00411         HwStatus hwst_diag;
00412         SystemStatusDiag sys_diag;
00413         BatteryStatusDiag batt_diag;
00414         ros::Timer timeout_timer;
00415         ros::Timer heartbeat_timer;
00416 
00417         ros::Publisher state_pub;
00418         ros::Publisher batt_pub;
00419         ros::ServiceServer rate_srv;
00420         ros::ServiceServer mode_srv;
00421 
00422         /* -*- mid-level helpers -*- */
00423 
00429         void process_statustext_normal(uint8_t severity, std::string &text) {
00430                 switch (severity) {
00431                 case MAV_SEVERITY_EMERGENCY:
00432                 case MAV_SEVERITY_ALERT:
00433                 case MAV_SEVERITY_CRITICAL:
00434                 case MAV_SEVERITY_ERROR:
00435                         ROS_ERROR_STREAM_NAMED("fcu", "FCU: " << text);
00436                         break;
00437 
00438                 case MAV_SEVERITY_WARNING:
00439                 case MAV_SEVERITY_NOTICE:
00440                         ROS_WARN_STREAM_NAMED("fcu", "FCU: " << text);
00441                         break;
00442 
00443                 case MAV_SEVERITY_INFO:
00444                         ROS_INFO_STREAM_NAMED("fcu", "FCU: " << text);
00445                         break;
00446 
00447                 case MAV_SEVERITY_DEBUG:
00448                 default:
00449                         ROS_DEBUG_STREAM_NAMED("fcu", "FCU: " << text);
00450                         break;
00451                 };
00452 
00453         }
00454 
00460         void process_statustext_apm_quirk(uint8_t severity, std::string &text) {
00461                 switch (severity) {
00462                 case 1: // SEVERITY_LOW
00463                         ROS_INFO_STREAM_NAMED("fcu", "FCU: " << text);
00464                         break;
00465 
00466                 case 2: // SEVERITY_MEDIUM
00467                         ROS_WARN_STREAM_NAMED("fcu", "FCU: " << text);
00468                         break;
00469 
00470                 case 3: // SEVERITY_HIGH
00471                 case 4: // SEVERITY_CRITICAL
00472                 case 5: // SEVERITY_USER_RESPONSE
00473                         ROS_ERROR_STREAM_NAMED("fcu", "FCU: " << text);
00474                         break;
00475 
00476                 default:
00477                         ROS_DEBUG_STREAM_NAMED("fcu", "FCU: UNK(" <<
00478                                         (int)severity << "): " << text);
00479                         break;
00480                 };
00481 
00482         }
00483 
00484         /* -*- message handlers -*- */
00485 
00486         void handle_heartbeat(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00487                 mavlink_heartbeat_t hb;
00488                 mavlink_msg_heartbeat_decode(msg, &hb);
00489                 hb_diag.tick(hb);
00490 
00491                 // update context && setup connection timeout
00492                 uas->update_heartbeat(hb.type, hb.autopilot);
00493                 uas->update_connection_status(true);
00494                 timeout_timer.stop();
00495                 timeout_timer.start();
00496 
00497                 mavros::StatePtr state_msg = boost::make_shared<mavros::State>();
00498                 state_msg->header.stamp = ros::Time::now();
00499                 state_msg->armed = hb.base_mode & MAV_MODE_FLAG_SAFETY_ARMED;
00500                 state_msg->guided = hb.base_mode & MAV_MODE_FLAG_GUIDED_ENABLED;
00501                 state_msg->mode = uas->str_mode_v10(hb.base_mode, hb.custom_mode);
00502 
00503                 state_pub.publish(state_msg);
00504         }
00505 
00506         void handle_sys_status(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00507                 mavlink_sys_status_t stat;
00508                 mavlink_msg_sys_status_decode(msg, &stat);
00509 
00510                 float volt = stat.voltage_battery / 1000.0;     // mV
00511                 float curr = stat.current_battery / 100.0;      // 10 mA or -1
00512                 float rem = stat.battery_remaining / 100.0;     // or -1
00513 
00514                 mavros::BatteryStatusPtr batt_msg = boost::make_shared<mavros::BatteryStatus>();
00515                 batt_msg->header.stamp = ros::Time::now();
00516                 batt_msg->voltage = volt;
00517                 batt_msg->current = curr;
00518                 batt_msg->remaining = rem;
00519 
00520                 sys_diag.set(stat);
00521                 batt_diag.set(volt, curr, rem);
00522                 batt_pub.publish(batt_msg);
00523         }
00524 
00525         void handle_statustext(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00526                 mavlink_statustext_t textm;
00527                 mavlink_msg_statustext_decode(msg, &textm);
00528 
00529                 std::string text(textm.text,
00530                                 strnlen(textm.text, sizeof(textm.text)));
00531 
00532                 if (uas->is_ardupilotmega())
00533                         process_statustext_apm_quirk(textm.severity, text);
00534                 else
00535                         process_statustext_normal(textm.severity, text);
00536         }
00537 
00538 #ifdef MAVLINK_MSG_ID_MEMINFO
00539         void handle_meminfo(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00540                 mavlink_meminfo_t mem;
00541                 mavlink_msg_meminfo_decode(msg, &mem);
00542                 mem_diag.set(mem.freemem, mem.brkval);
00543         }
00544 #endif
00545 
00546 #ifdef MAVLINK_MSG_ID_HWSTATUS
00547         void handle_hwstatus(const mavlink_message_t *msg, uint8_t sysid, uint8_t compid) {
00548                 mavlink_hwstatus_t hwst;
00549                 mavlink_msg_hwstatus_decode(msg, &hwst);
00550                 hwst_diag.set(hwst.Vcc, hwst.I2Cerr);
00551         }
00552 #endif
00553 
00554         /* -*- timer callbacks -*- */
00555 
00556         void timeout_cb(const ros::TimerEvent &event) {
00557                 uas->update_connection_status(false);
00558         }
00559 
00560         void heartbeat_cb(const ros::TimerEvent &event) {
00561                 mavlink_message_t msg;
00562                 mavlink_msg_heartbeat_pack_chan(UAS_PACK_CHAN(uas), &msg,
00563                                 MAV_TYPE_ONBOARD_CONTROLLER,
00564                                 MAV_AUTOPILOT_INVALID,
00565                                 MAV_MODE_MANUAL_ARMED,
00566                                 0,
00567                                 MAV_STATE_ACTIVE
00568                                 );
00569 
00570                 UAS_FCU(uas)->send_message(&msg);
00571         }
00572 
00573         /* -*- ros callbacks -*- */
00574 
00575         bool set_rate_cb(mavros::StreamRate::Request &req,
00576                         mavros::StreamRate::Response &res) {
00577 
00578                 mavlink_message_t msg;
00579                 mavlink_msg_request_data_stream_pack_chan(UAS_PACK_CHAN(uas), &msg,
00580                                 UAS_PACK_TGT(uas),
00581                                 req.stream_id,
00582                                 req.message_rate,
00583                                 (req.on_off)? 1 : 0
00584                                 );
00585 
00586                 UAS_FCU(uas)->send_message(&msg);
00587                 return true;
00588         }
00589 
00590         bool set_mode_cb(mavros::SetMode::Request &req,
00591                         mavros::SetMode::Response &res) {
00592                 mavlink_message_t msg;
00593                 uint8_t base_mode = req.base_mode;
00594                 uint32_t custom_mode = 0;
00595 
00596                 if (req.custom_mode != "") {
00597                         if (!uas->cmode_from_str(req.custom_mode, custom_mode)) {
00598                                 res.success = false;
00599                                 return true;
00600                         }
00601 
00602                         base_mode |= MAV_MODE_FLAG_CUSTOM_MODE_ENABLED;
00603                 }
00604 
00605                 mavlink_msg_set_mode_pack_chan(UAS_PACK_CHAN(uas), &msg,
00606                                 uas->get_tgt_system(),
00607                                 base_mode,
00608                                 custom_mode);
00609                 UAS_FCU(uas)->send_message(&msg);
00610                 res.success = true;
00611                 return true;
00612         }
00613 };
00614 
00615 }; // namespace mavplugin
00616 
00617 PLUGINLIB_EXPORT_CLASS(mavplugin::SystemStatusPlugin, mavplugin::MavRosPlugin)
00618 


mavros
Author(s): Vladimir Ermakov
autogenerated on Wed Aug 26 2015 12:29:13