19 #include <mavros_msgs/State.h> 20 #include <mavros_msgs/ExtendedState.h> 21 #include <mavros_msgs/StreamRate.h> 22 #include <mavros_msgs/SetMode.h> 23 #include <mavros_msgs/CommandLong.h> 24 #include <mavros_msgs/StatusText.h> 25 #include <mavros_msgs/VehicleInfo.h> 26 #include <mavros_msgs/VehicleInfoGet.h> 27 #include <mavros_msgs/MessageInterval.h> 30 #ifdef HAVE_SENSOR_MSGS_BATTERYSTATE_MSG 31 #include <sensor_msgs/BatteryState.h> 34 #include <mavros_msgs/BatteryStatus.h> 39 namespace std_plugins {
40 using mavlink::common::MAV_TYPE;
41 using mavlink::common::MAV_AUTOPILOT;
42 using mavlink::common::MAV_STATE;
70 std::lock_guard<std::mutex> lock(
mutex);
82 void tick(uint8_t type_, uint8_t autopilot_,
83 std::string &mode_, uint8_t system_status_)
85 std::lock_guard<std::mutex> lock(
mutex);
89 autopilot =
static_cast<MAV_AUTOPILOT
>(autopilot_);
96 std::lock_guard<std::mutex> lock(
mutex);
102 double freq = events / window;
108 stat.
summary(2,
"No events recorded.");
111 stat.
summary(1,
"Frequency too low.");
114 stat.
summary(1,
"Frequency too high.");
120 stat.
addf(
"Heartbeats since startup",
"%d",
count_);
121 stat.
addf(
"Frequency (Hz)",
"%f", freq);
157 void set(mavlink::common::msg::SYS_STATUS &st)
159 std::lock_guard<std::mutex> lock(
mutex);
164 std::lock_guard<std::mutex> lock(
mutex);
166 if ((last_st.onboard_control_sensors_health & last_st.onboard_control_sensors_enabled)
167 != last_st.onboard_control_sensors_enabled)
168 stat.
summary(2,
"Sensor health");
172 stat.
addf(
"Sensor present",
"0x%08X", last_st.onboard_control_sensors_present);
173 stat.
addf(
"Sensor enabled",
"0x%08X", last_st.onboard_control_sensors_enabled);
174 stat.
addf(
"Sensor health",
"0x%08X", last_st.onboard_control_sensors_health);
176 using STS = mavlink::common::MAV_SYS_STATUS_SENSOR;
201 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_GYRO))
202 stat.
add(
"3D gyro", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_GYRO)) ?
"Ok" :
"Fail");
203 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_ACCEL))
204 stat.
add(
"3D accelerometer", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_ACCEL)) ?
"Ok" :
"Fail");
205 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_MAG))
206 stat.
add(
"3D magnetometer", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_MAG)) ?
"Ok" :
"Fail");
207 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::ABSOLUTE_PRESSURE))
208 stat.
add(
"absolute pressure", (last_st.onboard_control_sensors_health &
enum_value(STS::ABSOLUTE_PRESSURE)) ?
"Ok" :
"Fail");
209 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::DIFFERENTIAL_PRESSURE))
210 stat.
add(
"differential pressure", (last_st.onboard_control_sensors_health &
enum_value(STS::DIFFERENTIAL_PRESSURE)) ?
"Ok" :
"Fail");
211 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::GPS))
212 stat.
add(
"GPS", (last_st.onboard_control_sensors_health &
enum_value(STS::GPS)) ?
"Ok" :
"Fail");
213 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::OPTICAL_FLOW))
214 stat.
add(
"optical flow", (last_st.onboard_control_sensors_health &
enum_value(STS::OPTICAL_FLOW)) ?
"Ok" :
"Fail");
215 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::VISION_POSITION))
216 stat.
add(
"computer vision position", (last_st.onboard_control_sensors_health &
enum_value(STS::VISION_POSITION)) ?
"Ok" :
"Fail");
217 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::LASER_POSITION))
218 stat.
add(
"laser based position", (last_st.onboard_control_sensors_health &
enum_value(STS::LASER_POSITION)) ?
"Ok" :
"Fail");
219 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::EXTERNAL_GROUND_TRUTH))
220 stat.
add(
"external ground truth (Vicon or Leica)", (last_st.onboard_control_sensors_health &
enum_value(STS::EXTERNAL_GROUND_TRUTH)) ?
"Ok" :
"Fail");
221 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::ANGULAR_RATE_CONTROL))
222 stat.
add(
"3D angular rate control", (last_st.onboard_control_sensors_health &
enum_value(STS::ANGULAR_RATE_CONTROL)) ?
"Ok" :
"Fail");
223 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::ATTITUDE_STABILIZATION))
224 stat.
add(
"attitude stabilization", (last_st.onboard_control_sensors_health &
enum_value(STS::ATTITUDE_STABILIZATION)) ?
"Ok" :
"Fail");
225 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::YAW_POSITION))
226 stat.
add(
"yaw position", (last_st.onboard_control_sensors_health &
enum_value(STS::YAW_POSITION)) ?
"Ok" :
"Fail");
227 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::Z_ALTITUDE_CONTROL))
228 stat.
add(
"z/altitude control", (last_st.onboard_control_sensors_health &
enum_value(STS::Z_ALTITUDE_CONTROL)) ?
"Ok" :
"Fail");
229 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::XY_POSITION_CONTROL))
230 stat.
add(
"x/y position control", (last_st.onboard_control_sensors_health &
enum_value(STS::XY_POSITION_CONTROL)) ?
"Ok" :
"Fail");
231 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::MOTOR_OUTPUTS))
232 stat.
add(
"motor outputs / control", (last_st.onboard_control_sensors_health &
enum_value(STS::MOTOR_OUTPUTS)) ?
"Ok" :
"Fail");
233 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::RC_RECEIVER))
234 stat.
add(
"rc receiver", (last_st.onboard_control_sensors_health &
enum_value(STS::RC_RECEIVER)) ?
"Ok" :
"Fail");
235 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_GYRO2))
236 stat.
add(
"2nd 3D gyro", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_GYRO2)) ?
"Ok" :
"Fail");
237 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_ACCEL2))
238 stat.
add(
"2nd 3D accelerometer", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_ACCEL2)) ?
"Ok" :
"Fail");
239 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SENSOR_3D_MAG2))
240 stat.
add(
"2nd 3D magnetometer", (last_st.onboard_control_sensors_health &
enum_value(STS::SENSOR_3D_MAG2)) ?
"Ok" :
"Fail");
241 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::GEOFENCE))
242 stat.
add(
"geofence", (last_st.onboard_control_sensors_health &
enum_value(STS::GEOFENCE)) ?
"Ok" :
"Fail");
243 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::AHRS))
244 stat.
add(
"AHRS subsystem health", (last_st.onboard_control_sensors_health &
enum_value(STS::AHRS)) ?
"Ok" :
"Fail");
245 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::TERRAIN))
246 stat.
add(
"Terrain subsystem health", (last_st.onboard_control_sensors_health &
enum_value(STS::TERRAIN)) ?
"Ok" :
"Fail");
247 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::REVERSE_MOTOR))
248 stat.
add(
"Motors are reversed", (last_st.onboard_control_sensors_health &
enum_value(STS::REVERSE_MOTOR)) ?
"Ok" :
"Fail");
249 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::LOGGING))
250 stat.
add(
"Logging", (last_st.onboard_control_sensors_health &
enum_value(STS::LOGGING)) ?
"Ok" :
"Fail");
251 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::BATTERY))
252 stat.
add(
"Battery", (last_st.onboard_control_sensors_health &
enum_value(STS::BATTERY)) ?
"Ok" :
"Fail");
253 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::PROXIMITY))
254 stat.
add(
"Proximity", (last_st.onboard_control_sensors_health &
enum_value(STS::PROXIMITY)) ?
"Ok" :
"Fail");
255 if (last_st.onboard_control_sensors_enabled &
enum_value(STS::SATCOM))
256 stat.
add(
"Satellite Communication", (last_st.onboard_control_sensors_health &
enum_value(STS::SATCOM)) ?
"Ok" :
"Fail");
259 stat.
addf(
"CPU Load (%)",
"%.1f", last_st.load / 10.0);
260 stat.
addf(
"Drop rate (%)",
"%.1f", last_st.drop_rate_comm / 10.0);
261 stat.
addf(
"Errors comm",
"%d", last_st.errors_comm);
262 stat.
addf(
"Errors count #1",
"%d", last_st.errors_count1);
263 stat.
addf(
"Errors count #2",
"%d", last_st.errors_count2);
264 stat.
addf(
"Errors count #3",
"%d", last_st.errors_count3);
265 stat.
addf(
"Errors count #4",
"%d", last_st.errors_count4);
289 std::lock_guard<std::mutex> lock(
mutex);
293 void set(
float volt,
float curr,
float rem) {
294 std::lock_guard<std::mutex> lock(
mutex);
302 std::lock_guard<std::mutex> lock(
mutex);
306 else if (voltage < min_voltage)
307 stat.
summary(1,
"Low voltage");
311 stat.
addf(
"Voltage",
"%.2f", voltage);
312 stat.
addf(
"Current",
"%.1f", current);
313 stat.
addf(
"Remaining",
"%.1f", remaining * 100);
337 void set(uint16_t
f, uint16_t
b) {
344 ssize_t freemem_ = freemem;
345 uint16_t brkval_ = brkval;
349 else if (freemem < 200)
354 stat.
addf(
"Free memory (B)",
"%zd", freemem_);
355 stat.
addf(
"Heap top",
"0x%04X", brkval_);
377 void set(uint16_t v, uint8_t
e) {
378 std::lock_guard<std::mutex> lock(
mutex);
385 std::lock_guard<std::mutex> lock(
mutex);
390 stat.
summary(1,
"Low voltage");
391 else if (i2cerr != i2cerr_last) {
392 i2cerr_last = i2cerr;
393 stat.
summary(1,
"New I2C error");
398 stat.
addf(
"Core voltage",
"%f", vcc);
399 stat.
addf(
"I2C errors",
"%zu", i2cerr);
420 hb_diag(
"Heartbeat", 10),
421 mem_diag(
"APM Memory"),
422 hwst_diag(
"APM Hardware"),
424 batt_diag(
"Battery"),
425 version_retries(RETRIES_COUNT),
427 has_battery_status(false),
428 battery_voltage(0.0),
429 conn_heartbeat_mav_type(
MAV_TYPE::ONBOARD_CONTROLLER)
434 PluginBase::initialize(uas_);
438 double conn_timeout_d;
439 double conn_heartbeat_d;
441 std::string conn_heartbeat_mav_type_str;
443 nh.param(
"conn/timeout", conn_timeout_d, 10.0);
444 nh.param(
"sys/min_voltage", min_voltage, 10.0);
445 nh.param(
"sys/disable_diag", disable_diag,
false);
448 if (nh.getParam(
"conn/heartbeat_rate", conn_heartbeat_d) && conn_heartbeat_d != 0.0) {
453 if (nh.getParam(
"conn/heartbeat_mav_type", conn_heartbeat_mav_type_str)) {
463 batt_diag.set_min_voltage(min_voltage);
468 timeout_timer = nh.createTimer(
ros::Duration(conn_timeout_d),
472 if (!conn_heartbeat.
isZero()) {
473 heartbeat_timer = nh.createTimer(conn_heartbeat,
481 autopilot_version_timer.stop();
483 state_pub = nh.advertise<mavros_msgs::State>(
"state", 10,
true);
484 extended_state_pub = nh.advertise<mavros_msgs::ExtendedState>(
"extended_state", 10);
485 batt_pub = nh.advertise<
BatteryMsg>(
"battery", 10);
486 statustext_pub = nh.advertise<mavros_msgs::StatusText>(
"statustext/recv", 10);
494 publish_disconnection();
495 enable_connection_cb();
534 static constexpr
int RETRIES_COUNT = 6;
540 using M_VehicleInfo = std::unordered_map<uint16_t, mavros_msgs::VehicleInfo>;
547 return sysid << 8 | compid;
552 auto key = get_vehicle_key(sysid, compid);
553 M_VehicleInfo::iterator ret = vehicles.find(key);
555 if (ret == vehicles.end()) {
557 mavros_msgs::VehicleInfo v;
560 v.available_info = 0;
562 auto res = vehicles.emplace(key, v);
577 using mavlink::common::MAV_SEVERITY;
619 memcpy(&b, array.data(),
sizeof(uint64_t));
628 std::snprintf(prefix,
sizeof(prefix),
"VER: %d.%d", sysid, compid);
630 ROS_INFO_NAMED(
"sys",
"%s: Capabilities 0x%016llx", prefix, (
long long int)apv.capabilities);
633 apv.flight_sw_version,
634 custom_version_to_hex_string(apv.flight_custom_version).c_str());
637 apv.middleware_sw_version,
638 custom_version_to_hex_string(apv.middleware_custom_version).c_str());
642 custom_version_to_hex_string(apv.os_custom_version).c_str());
643 ROS_INFO_NAMED(
"sys",
"%s: Board hardware: %08x", prefix, apv.board_version);
644 ROS_INFO_NAMED(
"sys",
"%s: VID/PID: %04x:%04x", prefix, apv.vendor_id, apv.product_id);
645 ROS_INFO_NAMED(
"sys",
"%s: UID: %016llx", prefix, (
long long int)apv.uid);
651 std::snprintf(prefix,
sizeof(prefix),
"VER: %d.%d", sysid, compid);
655 ROS_INFO_NAMED(
"sys",
"%s: Capabilities 0x%016llx", prefix, (
long long int)apv.capabilities);
658 apv.flight_sw_version,
659 8, apv.flight_custom_version.data());
662 apv.middleware_sw_version,
663 8, apv.middleware_custom_version.data());
667 8, apv.os_custom_version.data());
668 ROS_INFO_NAMED(
"sys",
"%s: Board hardware: %08x", prefix, apv.board_version);
669 ROS_INFO_NAMED(
"sys",
"%s: VID/PID: %04x:%04x", prefix, apv.vendor_id, apv.product_id);
670 ROS_INFO_NAMED(
"sys",
"%s: UID: %016llx", prefix, (
long long int)apv.uid);
674 auto state_msg = boost::make_shared<mavros_msgs::State>();
676 state_msg->connected =
false;
677 state_msg->armed =
false;
678 state_msg->guided =
false;
679 state_msg->mode =
"";
680 state_msg->system_status =
enum_value(MAV_STATE::UNINIT);
687 void handle_heartbeat(
const mavlink::mavlink_message_t *msg, mavlink::common::msg::HEARTBEAT &hb)
689 using mavlink::common::MAV_MODE_FLAG;
692 auto it = find_or_create_vehicle_info(msg->sysid, msg->compid);
694 auto vehicle_mode = m_uas->str_mode_v10(hb.base_mode, hb.custom_mode);
698 it->second.header.stamp = stamp;
699 it->second.available_info |= mavros_msgs::VehicleInfo::HAVE_INFO_HEARTBEAT;
700 it->second.autopilot = hb.autopilot;
701 it->second.type = hb.type;
702 it->second.system_status = hb.system_status;
703 it->second.base_mode = hb.base_mode;
704 it->second.custom_mode = hb.custom_mode;
705 it->second.mode = vehicle_mode;
707 if (!(hb.base_mode &
enum_value(MAV_MODE_FLAG::CUSTOM_MODE_ENABLED))) {
708 it->second.mode_id = hb.base_mode;
710 it->second.mode_id = hb.custom_mode;
714 if (!m_uas->is_my_target(msg->sysid, msg->compid)) {
715 ROS_DEBUG_NAMED(
"sys",
"HEARTBEAT from [%d, %d] dropped.", msg->sysid, msg->compid);
720 m_uas->update_heartbeat(hb.type, hb.autopilot, hb.base_mode);
721 m_uas->update_connection_status(
true);
722 timeout_timer.
stop();
723 timeout_timer.
start();
726 auto state_msg = boost::make_shared<mavros_msgs::State>();
727 state_msg->header.stamp = stamp;
728 state_msg->connected =
true;
729 state_msg->armed = !!(hb.base_mode &
enum_value(MAV_MODE_FLAG::SAFETY_ARMED));
730 state_msg->guided = !!(hb.base_mode &
enum_value(MAV_MODE_FLAG::GUIDED_ENABLED));
731 state_msg->mode = vehicle_mode;
732 state_msg->system_status = hb.system_status;
735 hb_diag.
tick(hb.type, hb.autopilot, state_msg->mode, hb.system_status);
740 auto state_msg = boost::make_shared<mavros_msgs::ExtendedState>();
742 state_msg->vtol_state = state.vtol_state;
743 state_msg->landed_state = state.landed_state;
745 extended_state_pub.
publish(state_msg);
748 void handle_sys_status(
const mavlink::mavlink_message_t *msg, mavlink::common::msg::SYS_STATUS &stat)
750 float volt = stat.voltage_battery / 1000.0f;
751 float curr = stat.current_battery / 100.0f;
752 float rem = stat.battery_remaining / 100.0f;
754 battery_voltage = volt;
756 batt_diag.
set(volt, curr, rem);
758 if (has_battery_status)
761 auto batt_msg = boost::make_shared<BatteryMsg>();
764 #ifdef HAVE_SENSOR_MSGS_BATTERYSTATE_MSG 765 batt_msg->voltage = volt;
766 batt_msg->current = -curr;
767 batt_msg->charge = NAN;
768 batt_msg->capacity = NAN;
769 batt_msg->design_capacity = NAN;
770 batt_msg->percentage = rem;
771 batt_msg->power_supply_status = BatteryMsg::POWER_SUPPLY_STATUS_DISCHARGING;
772 batt_msg->power_supply_health = BatteryMsg::POWER_SUPPLY_HEALTH_UNKNOWN;
773 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
774 batt_msg->present =
true;
775 batt_msg->cell_voltage.clear();
776 batt_msg->location =
"";
777 batt_msg->serial_number =
"";
778 #else // mavros_msgs::BatteryStatus 779 batt_msg->voltage = volt;
780 batt_msg->current = curr;
781 batt_msg->remaining = rem;
787 void handle_statustext(
const mavlink::mavlink_message_t *msg, mavlink::common::msg::STATUSTEXT &textm)
790 process_statustext_normal(textm.severity, text);
792 auto st_msg = boost::make_shared<mavros_msgs::StatusText>();
794 st_msg->severity = textm.severity;
796 statustext_pub.
publish(st_msg);
799 void handle_meminfo(
const mavlink::mavlink_message_t *msg, mavlink::ardupilotmega::msg::MEMINFO &mem)
801 mem_diag.
set(mem.freemem, mem.brkval);
804 void handle_hwstatus(
const mavlink::mavlink_message_t *msg, mavlink::ardupilotmega::msg::HWSTATUS &hwst)
806 hwst_diag.
set(hwst.Vcc, hwst.I2Cerr);
812 if (m_uas->is_my_target(msg->sysid, msg->compid)) {
813 autopilot_version_timer.
stop();
814 m_uas->update_capabilities(
true, apv.capabilities);
818 if (m_uas->is_ardupilotmega())
819 process_autopilot_version_apm_quirk(apv, msg->sysid, msg->compid);
821 process_autopilot_version_normal(apv, msg->sysid, msg->compid);
824 auto it = find_or_create_vehicle_info(msg->sysid, msg->compid);
828 it->second.available_info |= mavros_msgs::VehicleInfo::HAVE_INFO_AUTOPILOT_VERSION;
829 it->second.capabilities = apv.capabilities;
830 it->second.flight_sw_version = apv.flight_sw_version;
831 it->second.middleware_sw_version = apv.middleware_sw_version;
832 it->second.os_sw_version = apv.os_sw_version;
833 it->second.board_version = apv.board_version;
834 it->second.vendor_id = apv.vendor_id;
835 it->second.product_id = apv.product_id;
836 it->second.uid = apv.uid;
842 #ifdef HAVE_SENSOR_MSGS_BATTERYSTATE_MSG 843 using BT = mavlink::common::MAV_BATTERY_TYPE;
845 has_battery_status =
true;
847 auto batt_msg = boost::make_shared<BatteryMsg>();
850 batt_msg->voltage = battery_voltage;
851 batt_msg->current = -(bs.current_battery / 100.0f);
852 batt_msg->charge = NAN;
853 batt_msg->capacity = NAN;
854 batt_msg->design_capacity = NAN;
855 batt_msg->percentage = bs.battery_remaining / 100.0f;
856 batt_msg->power_supply_status = BatteryMsg::POWER_SUPPLY_STATUS_DISCHARGING;
857 batt_msg->power_supply_health = BatteryMsg::POWER_SUPPLY_HEALTH_UNKNOWN;
874 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_LIPO;
877 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_LIFE;
880 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_LION;
883 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_NIMH;
887 batt_msg->power_supply_technology = BatteryMsg::POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
892 batt_msg->present =
true;
894 batt_msg->cell_voltage.clear();
895 batt_msg->cell_voltage.reserve(bs.voltages.size());
896 for (
auto v : bs.voltages) {
900 batt_msg->cell_voltage.push_back(v / 1000.0
f);
904 batt_msg->serial_number =
"";
914 m_uas->update_connection_status(
false);
919 using mavlink::common::MAV_MODE;
921 mavlink::common::msg::HEARTBEAT hb {};
923 hb.type =
enum_value(conn_heartbeat_mav_type);
924 hb.autopilot =
enum_value(MAV_AUTOPILOT::INVALID);
925 hb.base_mode =
enum_value(MAV_MODE::MANUAL_ARMED);
927 hb.system_status =
enum_value(MAV_STATE::ACTIVE);
929 UAS_FCU(m_uas)->send_message_ignore_drop(hb);
934 using mavlink::common::MAV_CMD;
939 bool do_broadcast = version_retries > RETRIES_COUNT / 2;
942 auto client = nh.
serviceClient<mavros_msgs::CommandLong>(
"cmd/command");
944 mavros_msgs::CommandLong
cmd{};
946 cmd.request.broadcast = do_broadcast;
947 cmd.request.command =
enum_value(MAV_CMD::REQUEST_AUTOPILOT_CAPABILITIES);
948 cmd.request.confirmation =
false;
949 cmd.request.param1 = 1.0;
952 (do_broadcast) ?
"broadcast" :
"unicast");
953 ret = client.call(
cmd);
961 if (version_retries > 0) {
964 "VER: %s request timeout, retries left %d",
965 (do_broadcast) ?
"broadcast" :
"unicast",
969 m_uas->update_capabilities(
false);
970 autopilot_version_timer.
stop();
971 ROS_WARN_NAMED(
"sys",
"VER: your FCU don't support AUTOPILOT_VERSION, " 972 "switched to default capabilities");
978 has_battery_status =
false;
981 version_retries = RETRIES_COUNT;
983 autopilot_version_timer.
start();
985 autopilot_version_timer.
stop();
988 if (connected && disable_diag && m_uas->is_ardupilotmega()) {
999 publish_disconnection();
1009 mavlink::common::msg::STATUSTEXT statustext {};
1010 statustext.severity = req->severity;
1014 "Status text too long: truncating...");
1017 UAS_FCU(m_uas)->send_message_ignore_drop(statustext);
1023 mavros_msgs::StreamRate::Response &res)
1025 mavlink::common::msg::REQUEST_DATA_STREAM rq;
1027 rq.target_system = m_uas->get_tgt_system();
1028 rq.target_component = m_uas->get_tgt_component();
1029 rq.req_stream_id = req.stream_id;
1030 rq.req_message_rate = req.message_rate;
1031 rq.start_stop = (req.on_off) ? 1 : 0;
1033 UAS_FCU(m_uas)->send_message_ignore_drop(rq);
1038 mavros_msgs::SetMode::Response &res)
1040 using mavlink::common::MAV_MODE_FLAG;
1042 uint8_t base_mode = req.base_mode;
1043 uint32_t custom_mode = 0;
1045 if (req.custom_mode !=
"") {
1046 if (!m_uas->cmode_from_str(req.custom_mode, custom_mode)) {
1047 res.mode_sent =
false;
1056 base_mode |= (m_uas->get_armed()) ?
enum_value(MAV_MODE_FLAG::SAFETY_ARMED) : 0;
1057 base_mode |= (m_uas->get_hil_state()) ?
enum_value(MAV_MODE_FLAG::HIL_ENABLED) : 0;
1058 base_mode |=
enum_value(MAV_MODE_FLAG::CUSTOM_MODE_ENABLED);
1061 mavlink::common::msg::SET_MODE sm;
1062 sm.target_system = m_uas->get_tgt_system();
1063 sm.base_mode = base_mode;
1064 sm.custom_mode = custom_mode;
1066 UAS_FCU(m_uas)->send_message_ignore_drop(sm);
1067 res.mode_sent =
true;
1072 mavros_msgs::VehicleInfoGet::Response &res)
1076 for (
const auto &got : vehicles) {
1077 res.vehicles.emplace_back(got.second);
1084 uint8_t req_sysid = req.sysid;
1085 uint8_t req_compid = req.compid;
1087 if (req.sysid == 0 && req.compid == 0) {
1089 req_sysid = m_uas->get_tgt_system();
1090 req_compid = m_uas->get_tgt_component();
1093 uint16_t key = get_vehicle_key(req_sysid, req_compid);
1094 auto it = vehicles.find(key);
1096 if (it == vehicles.end()) {
1098 res.success =
false;
1102 res.vehicles.emplace_back(it->second);
1108 mavros_msgs::MessageInterval::Response &res)
1110 using mavlink::common::MAV_CMD;
1113 auto client = nh.
serviceClient<mavros_msgs::CommandLong>(
"cmd/command");
1117 if (req.message_rate < 0) {
1118 interval_us = -1.0f;
1119 }
else if (req.message_rate == 0) {
1122 interval_us = 1000000.0f / req.message_rate;
1125 mavros_msgs::CommandLong
cmd{};
1127 cmd.request.broadcast =
false;
1128 cmd.request.command =
enum_value(MAV_CMD::SET_MESSAGE_INTERVAL);
1129 cmd.request.confirmation =
false;
1130 cmd.request.param1 = req.message_id;
1131 cmd.request.param2 = interval_us;
1133 ROS_DEBUG_NAMED(
"sys",
"SetMessageInterval: Request msgid %u at %f hz",
1134 req.message_id, req.message_rate);
1135 res.success = client.call(
cmd);
1141 ROS_ERROR_COND_NAMED(!res.success,
"sys",
"SetMessageInterval: command plugin service call failed!");
MemInfo(const std::string &name)
MAVROS Plugin base class.
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
#define ROS_ERROR_COND_NAMED(cond, name,...)
#define ROS_WARN_COND_NAMED(cond, name,...)
MAV_TYPE conn_heartbeat_mav_type
std::shared_ptr< MAVConnInterface const > ConstPtr
ros::Publisher statustext_pub
bool set_mode_cb(mavros_msgs::SetMode::Request &req, mavros_msgs::SetMode::Response &res)
#define ROS_INFO_NAMED(name,...)
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
std::atomic< uint16_t > brkval
#define ROS_DEBUG_STREAM_NAMED(name, args)
std::string format(const std::string &fmt, Args...args)
void heartbeat_cb(const ros::TimerEvent &event)
std::vector< ros::Time > times_
mavros_msgs::BatteryStatus BatteryMsg
void publish(const boost::shared_ptr< M > &message) const
bool vehicle_info_get_cb(mavros_msgs::VehicleInfoGet::Request &req, mavros_msgs::VehicleInfoGet::Response &res)
#define ROS_ERROR_STREAM_NAMED(name, args)
#define ROS_WARN_NAMED(name,...)
System status diagnostic updater.
const size_t window_size_
void summary(unsigned char lvl, const std::string s)
std::unordered_map< uint16_t, mavros_msgs::VehicleInfo > M_VehicleInfo
void statustext_cb(const mavros_msgs::StatusText::ConstPtr &req)
ros::Subscriber statustext_sub
void process_autopilot_version_apm_quirk(mavlink::common::msg::AUTOPILOT_VERSION &apv, uint8_t sysid, uint8_t compid)
void handle_autopilot_version(const mavlink::mavlink_message_t *msg, mavlink::common::msg::AUTOPILOT_VERSION &apv)
void handle_sys_status(const mavlink::mavlink_message_t *msg, mavlink::common::msg::SYS_STATUS &stat)
void tick(uint8_t type_, uint8_t autopilot_, std::string &mode_, uint8_t system_status_)
void set(float volt, float curr, float rem)
void handle_battery_status(const mavlink::mavlink_message_t *msg, mavlink::common::msg::BATTERY_STATUS &bs)
ros::Timer autopilot_version_timer
#define UAS_DIAG(uasobjptr)
helper accessor to diagnostic updater
#define ROS_INFO_STREAM_NAMED(name, args)
void process_autopilot_version_normal(mavlink::common::msg::AUTOPILOT_VERSION &apv, uint8_t sysid, uint8_t compid)
void timeout_cb(const ros::TimerEvent &event)
void addf(const std::string &key, const char *format,...)
Memory usage diag (APM-only)
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
SystemStatusDiag sys_diag
mavlink::common::msg::SYS_STATUS last_st
bool set_message_interval_cb(mavros_msgs::MessageInterval::Request &req, mavros_msgs::MessageInterval::Response &res)
bool set_rate_cb(mavros_msgs::StreamRate::Request &req, mavros_msgs::StreamRate::Response &res)
uint16_t get_vehicle_key(uint8_t sysid, uint8_t compid)
ros::ServiceServer rate_srv
#define ROS_DEBUG_NAMED(name,...)
void handle_extended_sys_state(const mavlink::mavlink_message_t *msg, mavlink::common::msg::EXTENDED_SYS_STATE &state)
ros::ServiceServer vehicle_info_get_srv
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
void handle_hwstatus(const mavlink::mavlink_message_t *msg, mavlink::ardupilotmega::msg::HWSTATUS &hwst)
void handle_statustext(const mavlink::mavlink_message_t *msg, mavlink::common::msg::STATUSTEXT &textm)
mavlink::common::MAV_TYPE mav_type_from_str(const std::string &mav_type)
Retreive MAV_TYPE from name.
ros::Timer heartbeat_timer
void handle_meminfo(const mavlink::mavlink_message_t *msg, mavlink::ardupilotmega::msg::MEMINFO &mem)
#define UAS_FCU(uasobjptr)
helper accessor to FCU link interface
void set_string_z(std::array< char, _N > &a, const std::string &s)
std::atomic< ssize_t > freemem
HeartbeatStatus(const std::string &name, size_t win_size)
std::string to_string(timesync_mode e)
SystemStatusDiag(const std::string &name)
ros::ServiceServer mode_srv
void publish_disconnection()
HwStatus(const std::string &name)
Battery diagnostic updater.
void initialize(UAS &uas_)
Plugin initializer.
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
BatteryStatusDiag batt_diag
ros::Publisher extended_state_pub
void handle_heartbeat(const mavlink::mavlink_message_t *msg, mavlink::common::msg::HEARTBEAT &hb)
void autopilot_version_cb(const ros::TimerEvent &event)
const std::string & getName()
DiagnosticTask(const std::string name)
Subscriptions get_subscriptions()
Return vector of MAVLink message subscriptions (handlers)
BatteryStatusDiag(const std::string &name)
std::vector< HandlerInfo > Subscriptions
Subscriptions vector.
#define ROS_ERROR_NAMED(name,...)
ros::ServiceServer message_interval_srv
void connection_cb(bool connected) override
M_VehicleInfo::iterator find_or_create_vehicle_info(uint8_t sysid, uint8_t compid)
static std::string custom_version_to_hex_string(std::array< uint8_t, 8 > &array)
void add(const std::string &key, const T &val)
#define PLUGINLIB_EXPORT_CLASS(class_type, base_class_type)
void set(uint16_t v, uint8_t e)
void set(uint16_t f, uint16_t b)
void run(diagnostic_updater::DiagnosticStatusWrapper &stat)
std::string to_string(const std::array< char, _N > &a)
Hardware status (APM-only)
std::vector< int > seq_nums_
void set(mavlink::common::msg::SYS_STATUS &st)
void process_statustext_normal(uint8_t severity, std::string &text)
constexpr std::underlying_type< _T >::type enum_value(_T e)
std::recursive_mutex mutex
#define ROS_WARN_STREAM_NAMED(name, args)
void set_min_voltage(float volt)