20 #include <mavlink/config.h> 21 #include <mavconn/mavlink_dialect.h> 24 #include <std_msgs/String.h> 29 using mavlink::mavlink_message_t;
35 mavlink_nh(
"mavlink"),
36 fcu_link_diag(
"FCU connection"),
37 gcs_link_diag(
"GCS bridge"),
38 plugin_loader(
"mavros",
"mavros::plugin::PluginBase"),
39 last_message_received_from_gcs(0),
40 plugin_subscriptions{}
42 std::string fcu_url, gcs_url;
43 std::string fcu_protocol;
44 int system_id, component_id;
45 int tgt_system_id, tgt_component_id;
47 double conn_timeout_d;
53 nh.
param<std::string>(
"fcu_url", fcu_url,
"serial:///dev/ttyACM0");
54 nh.
param<std::string>(
"gcs_url", gcs_url,
"udp://@");
56 nh.
param(
"conn/timeout", conn_timeout_d, 30.0);
58 nh.
param<std::string>(
"fcu_protocol", fcu_protocol,
"v2.0");
59 nh.
param(
"system_id", system_id, 1);
61 nh.
param(
"target_system_id", tgt_system_id, 1);
62 nh.
param(
"target_component_id", tgt_component_id, 1);
63 nh.
param(
"startup_px4_usb_quirk", px4_usb_quirk,
false);
64 nh.
getParam(
"plugin_blacklist", plugin_blacklist);
65 nh.
getParam(
"plugin_whitelist", plugin_whitelist);
76 system_id = fcu_link->get_system_id();
77 component_id = fcu_link->get_component_id();
88 if (fcu_protocol ==
"v1.0") {
91 else if (fcu_protocol ==
"v2.0") {
98 ROS_WARN(
"Unknown FCU protocol: \"%s\", should be: \"v1.0\" or \"v2.0\". Used default v1.0.", fcu_protocol.c_str());
124 .unreliable().maxDatagramSize(1024)
136 if (plugin_blacklist.empty() and !plugin_whitelist.empty())
137 plugin_blacklist.emplace_back(
"*");
150 if (this->gcs_quiet_mode && msg->msgid != mavlink::minimal::msg::HEARTBEAT::MSG_ID &&
151 (
ros::Time::now() - this->last_message_received_from_gcs > this->conn_timeout)) {
155 gcs_link->send_message_ignore_drop(msg);
159 fcu_link->port_closed_cb = []() {
160 ROS_ERROR(
"FCU connection closed, mavros will be terminated.");
168 fcu_link->send_message_ignore_drop(msg);
177 std::stringstream ss;
181 ROS_INFO(
"Built-in SIMD instructions: %s", Eigen::SimdInstructionSetsInUse());
183 ROS_INFO(
"Known MAVLink dialects:%s", ss.str().c_str());
184 ROS_INFO(
"MAVROS started. MY ID %u.%u, TARGET ID %u.%u",
185 system_id, component_id,
186 tgt_system_id, tgt_component_id);
206 static auto finished =
false;
211 if (
const auto* p = dynamic_cast<mavconn::MAVConnUDP*>(
gcs_link.get())) {
212 const auto endpoint = p->get_remote_endpoint();
213 const auto endpoint_valid = endpoint.find(
"255.255.255.255") == std::string::npos;
215 if (endpoint_valid) {
216 std_msgs::String
msg;
217 msg.data = endpoint.substr(0, endpoint.find(
":"));
223 remote_endpoint_timer.
start();
234 auto rmsg = boost::make_shared<mavros_msgs::Mavlink>();
251 ROS_ERROR(
"Drop mavlink packet: convert error.");
260 for (
auto &info : it->second)
261 std::get<3>(info)(mmsg, framing);
266 int cmp = fnmatch(pattern.c_str(), pl_name.c_str(), FNM_CASEFOLD);
269 else if (cmp != FNM_NOMATCH) {
271 ROS_FATAL(
"Plugin list check error! fnmatch('%s', '%s', FNM_CASEFOLD) -> %d",
272 pattern.c_str(), pl_name.c_str(), cmp);
293 for (
auto &bl_pattern : blacklist) {
295 for (
auto &wl_pattern : whitelist) {
328 for (
auto &info : plugin->get_subscriptions()) {
329 auto msgid = std::get<0>(info);
330 auto msgname = std::get<1>(info);
331 auto type_hash_ = std::get<2>(info);
333 std::string log_msgname;
336 log_msgname =
utils::format(
"MSG-ID (%u) <%zu>", msgid, type_hash_);
338 log_msgname =
utils::format(
"%s (%u) <%zu>", msgname, msgid, type_hash_);
353 if (!append_allowed) {
354 append_allowed =
true;
355 for (
auto &
e : it->second) {
356 auto t2 = std::get<2>(
e);
358 ROS_ERROR_STREAM(log_msgname <<
" routed to different message type (hash: " <<
t2 <<
")");
359 append_allowed =
false;
364 if (append_allowed) {
366 it->second.emplace_back(info);
369 ROS_ERROR_STREAM(log_msgname <<
" handler dropped because this ID are used for another message type");
385 const uint8_t init[] = {0x0d, 0x0d, 0x0d, 0};
386 const uint8_t nsh[] =
"sh /etc/init.d/rc.usb\n";
388 ROS_INFO(
"Autostarting mavlink via USB on PX4");
400 ROS_INFO(
"CON: Got HEARTBEAT, connected. FCU: %s", ap.c_str());
402 ROS_WARN(
"CON: Lost connection, HEARTBEAT timed out.");
UAS mav_uas
UAS object passed to all plugins.
MAVROS Plugin base class.
static bool pattern_match(std::string &pattern, std::string &pl_name)
void add_plugin(std::string &pl_name, ros::V_string &blacklist, ros::V_string &whitelist)
load plugin
std::shared_ptr< MAVConnInterface const > ConstPtr
std::string format(const std::string &fmt, Args...args)
void publish(const boost::shared_ptr< M > &message) const
MAV_AUTOPILOT get_autopilot()
Returns autopilot type.
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
void setHardwareID(const std::string &hwid)
diagnostic_updater::Updater gcs_diag_updater
bool convert(const mavros_msgs::Mavlink &rmsg, mavlink_message_t &mmsg)
MavRos node implementation class.
void log_connect_change(bool connected)
void add(const std::string &name, TaskFunction f)
ros::Subscriber mavlink_sub
#define UAS_DIAG(uasobjptr)
helper accessor to diagnostic updater
static constexpr auto MAV_COMP_ID_UDP_BRIDGE
std::unordered_map< mavlink::msgid_t, plugin::PluginBase::Subscriptions > plugin_subscriptions
FCU link -> router -> plugin handler.
void mavlink_sub_cb(const mavros_msgs::Mavlink::ConstPtr &rmsg)
ros -> fcu link
void set_connection_status(bool connected)
void mavlink_pub_cb(const mavlink::mavlink_message_t *mmsg, const mavconn::Framing framing)
fcu link -> ros
std::vector< std::string > V_string
ros::Publisher mavlink_pub
bool param(const std::string ¶m_name, T ¶m_val, const T &default_val) const
mavconn::MAVConnInterface::Ptr gcs_link
std::vector< std::string > getDeclaredClasses()
void add_connection_change_handler(ConnectionCb cb)
Add connection change handler callback.
#define UAS_FCU(uasobjptr)
helper accessor to FCU link interface
ros::Duration conn_timeout
bool is_mavlink_message_t(const size_t rt)
void set_tgt(uint8_t sys, uint8_t comp)
std::string to_string(timesync_mode e)
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
MAVConnInterface(const MAVConnInterface &)=delete
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
void plugin_route_cb(const mavlink::mavlink_message_t *mmsg, const mavconn::Framing framing)
message router
#define ROS_DEBUG_STREAM(args)
ros::Time last_message_received_from_gcs
static bool is_blacklisted(std::string &pl_name, ros::V_string &blacklist, ros::V_string &whitelist)
Checks that plugin blacklisted.
struct __mavlink_message mavlink_message_t
static std::vector< std::string > get_known_dialects()
static Ptr open_url(std::string url, uint8_t system_id=1, uint8_t component_id=MAV_COMP_ID_UDP_BRIDGE)
ROSCPP_DECL void requestShutdown()
uint32_t getNumSubscribers() const
#define ROS_INFO_STREAM(args)
void startup_px4_usb_quirk()
start mavlink app on USB
bool getParam(const std::string &key, std::string &s) const
pluginlib::ClassLoader< plugin::PluginBase > plugin_loader
std::vector< plugin::PluginBase::Ptr > loaded_plugins
MavlinkDiag gcs_link_diag
ROSCPP_DECL void shutdown()
#define ROS_ERROR_STREAM(args)
MavlinkDiag fcu_link_diag
ros::NodeHandle mavlink_nh
void set_mavconn(const mavconn::MAVConnInterface::Ptr &link)
ROSCPP_DECL void waitForShutdown()
constexpr std::underlying_type< _T >::type enum_value(_T e)
std::shared_ptr< MAVConnInterface > Ptr