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 last_message_received_from_gcs(0),
37 fcu_link_diag(
"FCU connection"),
38 gcs_link_diag(
"GCS bridge"),
39 plugin_loader(
"mavros",
"mavros::plugin::PluginBase"),
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://@");
55 nh.param<
bool>(
"gcs_quiet_mode", gcs_quiet_mode,
false);
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);
68 std::string base_link_frame_id, odom_frame_id, map_frame_id;
69 if (nh.param<std::string>(
"base_link_frame_id", base_link_frame_id,
"base_link"))
70 ROS_INFO(
"Find param base_link_frame_id: %s", base_link_frame_id.c_str());
71 if (nh.param<std::string>(
"odom_frame_id", odom_frame_id,
"odom"))
72 ROS_INFO(
"Find param odom_frame_id: %s", odom_frame_id.c_str());
73 if (nh.param<std::string>(
"map_frame_id", map_frame_id,
"map"))
74 ROS_INFO(
"Find param map_frame_id: %s", map_frame_id.c_str());
75 mav_uas.set_base_link_frame_id(base_link_frame_id);
76 mav_uas.set_odom_frame_id(odom_frame_id);
77 mav_uas.set_map_frame_id(map_frame_id);
78 mav_uas.setup_static_tf();
83 UAS_DIAG(&mav_uas).setHardwareID(fcu_url);
89 system_id = fcu_link->get_system_id();
90 component_id = fcu_link->get_component_id();
92 fcu_link_diag.set_mavconn(fcu_link);
93 UAS_DIAG(&mav_uas).add(fcu_link_diag);
101 if (fcu_protocol ==
"v1.0") {
104 else if (fcu_protocol ==
"v2.0") {
111 ROS_WARN(
"Unknown FCU protocol: \"%s\", should be: \"v1.0\" or \"v2.0\". Used default v1.0.", fcu_protocol.c_str());
120 gcs_link_diag.set_mavconn(
gcs_link);
121 gcs_diag_updater.setHardwareID(gcs_url);
122 gcs_diag_updater.add(gcs_link_diag);
134 mavlink_pub = mavlink_nh.advertise<mavros_msgs::Mavlink>(
"from", 100);
141 mav_uas.set_tgt(tgt_system_id, tgt_component_id);
149 if (plugin_blacklist.empty() and !plugin_whitelist.empty())
150 plugin_blacklist.emplace_back(
"*");
152 for (
auto &name : plugin_loader.getDeclaredClasses())
153 add_plugin(name, plugin_blacklist, plugin_whitelist);
159 [
this](
const mavlink_message_t *msg,
const Framing framing) {
161 plugin_route_cb(msg, framing);
164 if (this->gcs_quiet_mode &&
msg->msgid != mavlink::minimal::msg::HEARTBEAT::MSG_ID &&
165 (
ros::Time::now() - this->last_message_received_from_gcs > this->conn_timeout)) {
169 gcs_link->send_message_ignore_drop(msg);
173 ROS_ERROR(
"FCU connection closed, mavros will be terminated.");
179 gcs_link->connect([
this, fcu_link](
const mavlink_message_t *msg,
const Framing framing) {
181 fcu_link->send_message_ignore_drop(msg);
184 gcs_link_diag.set_connection_status(
true);
188 startup_px4_usb_quirk();
190 std::stringstream ss;
194 ROS_INFO(
"Built-in SIMD instructions: %s", Eigen::SimdInstructionSetsInUse());
195 ROS_INFO(
"Built-in MAVLink package version: %s", MAVLINK_VERSION);
196 ROS_INFO(
"Known MAVLink dialects:%s", ss.str().c_str());
197 ROS_INFO(
"MAVROS started. MY ID %u.%u, TARGET ID %u.%u",
198 system_id, component_id,
199 tgt_system_id, tgt_component_id);
219 static auto finished =
false;
225 const auto endpoint = p->get_remote_endpoint();
226 const auto endpoint_valid = endpoint.find(
"255.255.255.255") == std::string::npos;
228 if (endpoint_valid) {
229 std_msgs::String
msg;
230 msg.data = endpoint.substr(0, endpoint.find(
":"));
236 remote_endpoint_timer.
start();
247 auto rmsg = boost::make_shared<mavros_msgs::Mavlink>();
259 mavlink_message_t mmsg;
264 ROS_ERROR(
"Drop mavlink packet: convert error.");
273 for (
auto &info : it->second)
274 std::get<3>(info)(mmsg, framing);
279 int cmp = fnmatch(pattern.c_str(), pl_name.c_str(), FNM_CASEFOLD);
282 else if (cmp != FNM_NOMATCH) {
284 ROS_FATAL(
"Plugin list check error! fnmatch('%s', '%s', FNM_CASEFOLD) -> %d",
285 pattern.c_str(), pl_name.c_str(), cmp);
306 for (
auto &bl_pattern : blacklist) {
308 for (
auto &wl_pattern : whitelist) {
322 static const auto h =
typeid(mavlink_message_t).hash_code();
341 for (
auto &info : plugin->get_subscriptions()) {
342 auto msgid = std::get<0>(info);
343 auto msgname = std::get<1>(info);
344 auto type_hash_ = std::get<2>(info);
346 std::string log_msgname;
349 log_msgname =
utils::format(
"MSG-ID (%u) <%zu>", msgid, type_hash_);
351 log_msgname =
utils::format(
"%s (%u) <%zu>", msgname, msgid, type_hash_);
366 if (!append_allowed) {
367 append_allowed =
true;
368 for (
auto &e : it->second) {
369 auto t2 = std::get<2>(e);
371 ROS_ERROR_STREAM(log_msgname <<
" routed to different message type (hash: " << t2 <<
")");
372 append_allowed =
false;
377 if (append_allowed) {
379 it->second.emplace_back(info);
382 ROS_ERROR_STREAM(log_msgname <<
" handler dropped because this ID are used for another message type");
398 const uint8_t
init[] = {0x0d, 0x0d, 0x0d, 0};
399 const uint8_t nsh[] =
"sh /etc/init.d/rc.usb\n";
401 ROS_INFO(
"Autostarting mavlink via USB on PX4");
413 ROS_INFO(
"CON: Got HEARTBEAT, connected. FCU: %s", ap.c_str());
415 ROS_WARN(
"CON: Lost connection, HEARTBEAT timed out.");