跳至内容

从 MAVROS 向 PX4 发送自定义信息

警告

本文已通过测试:

  • 乌班图 20.04
  • ROS: Noetic
  • PX4 固件: v1.13

不过,这些步骤都比较笼统,因此其他发行版/版本的用户几乎无需修改即可使用。

MAVROS 安装

跟进 源装置 来自 mavlink/mavros 安装 "ROS Kinetic"。

马弗罗斯

  1. 我们首先创建一个新的 MAVROS 插件,在本例中名为 keyboard_command.cpp (在 workspace/src/mavros/mavros_extras/src/plugins),请使用下面的代码:

    代码从 ROS 主题订阅一条 'char' 消息 /mavros/keyboard_command/keyboard_sub 并将其作为 MAVLink 信息发送。

    c
     #include <mavros/mavros_plugin.h>;
     #include <pluginlib/class_list_macros.h>;
     #include iostream>;
     #include <std_msgs/Char.h>;
    
     名称空间 mavros {
     命名空间 extra_plugins{
    
     class KeyboardCommandPlugin : public plugin::PluginBase {
     公众:
         键盘命令插件() : 插件库(),
             nh("~keyboard_command";)
    
        { };
    
         空白 初始化(UAS 及样品;uas_)
         {
             PluginBase::initialize(uas_);
             键盘子 = nh.订阅("keyboard_sub";, 10, 及样品;KeyboardCommandPlugin::keyboard_cb, this);
         };
    
         订阅 获取订阅()
         {
             返回 {/* 禁用 RX */ };
         }
    
     私人
         ros::NodeHandle nh;
         ros::Subscriber keyboard_sub;
    
        空白 键盘_cb( std_msgs::Char::ConstPtr 及样品;req)
         {
             std::cout <<; "Got Char : "; <<; req->数据 <<;  std::endl;
             mavlink::common::msg::KEY_COMMAND kc {};
             kc.command = req->数据;
             UAS_FCU(m_uas)->;发送信息忽略删除(kc);
         }
     };
     }   // 名称空间 extra_plugins
     }   // 命名空间 mavros
    
    pluginlib_export_class(mavros::extra_plugins::KeyboardCommandPlugin, mavros::plugin::PluginBase)
  2. 编辑 mavros_plugins.xml (在 workspace/src/mavros/mavros_extras) 并添加以下几行:

    xml
    <; 名字="keyboard_command"; 类型="mavros::extra_plugins::KeyboardCommandPlugin"; 基类类型="mavros::plugin::PluginBase";>;
         <;描述>接受键盘命令。描述>;
    </>;
  3. 编辑 CMakeLists.txt (在 workspace/src/mavros/mavros_extras) 并在 add_library.

    cmake
    add_library( 
    ...
      src/plugins/keyboard_command.cpp 
    )
  4. 内部 common.xmlworkspace/src/mavlink/message_definitions/v1.0),复制以下几行,添加您的 MAVLink 信息:

    xml
    ...
      <;信息 本我="229"; 名字="KEY_COMMAND";>;
         <;描述>键盘字符命令。描述>;
         <;领域 类型="char"; 名字="命令";> </领域>;
       </信息>;
    ...

PX4 的变化

  1. 内部 common.xml (在 PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0),按以下步骤添加您的 MAVLink 信息(步骤与上述 MAVROS 部分相同):

    xml
    ...
      <;信息 本我="229"; 名字="KEY_COMMAND";>;
         <;描述>键盘字符命令。描述>;
         <;领域 类型="char"; 名字="命令";> </领域>;
       </信息>;
    ...

    警告

    确保 common.xml 文件完全相同:

    • PX4-Autopilot/src/modules/mavlink/mavlink/message_definitions/v1.0
    • workspace/src/mavlink/message_definitions/v1.0 完全相同。
  2. 制作自己的 uORB 信息文件 key_command.msg 中的 (PX4-Autopilot/msg)。在本例中,"key_command.msg"只有代码:

    uint64 timestamp # 自系统启动以来的时间(微秒)
    char cmd

    然后,在 CMakeLists.txt (在 PX4-Autopilot/msg),包括

    cmake
    设置(
    ...
         key_command.msg
         )
  3. 编辑 mavlink_receiver.h (在 PX4-Autopilot/src/modules/mavlink)

    cpp
    ...
    #include <uORB/topics/key_command.h>;
    ...
     MavlinkReceiver
    {
    ...
    私人
        空白 处理消息键命令(mavlink_message_t *信息);
    ...
        orb_advert_t _key_command_pub{nullptr};
    }
  4. 编辑 mavlink_receiver.cpp (在 PX4-Autopilot/src/modules/mavlink).此时,PX4 会接收 ROS 发送的 MAVLink 消息,并将其作为 uORB 主题发布。

    cpp
    ...
    空白 MavlinkReceiver::处理信息(mavlink_message_t *信息)
    {
    ...
     个案 mavlink_msg_id_key_command:
            处理消息键命令(毫秒);
            断裂;
    ...
    }
    ...
    空白
    MavlinkReceiver::处理消息键命令(mavlink_message_t *msg)
    {
        mavlink_key_command_t 男人:
        mavlink_msg_key_command_decode(msg、 及样品;人);
    
    结构 key_command_s 密钥 = {};
    
        key.timestamp = hrt_absolute_time();
        key.cmd = man.command;
    
        如果 (_key_command_pub == nullptr) {
            _key_command_pub(密钥命令发布 = 广告(ORB_ID(key_command)、 及样品;键);
    
        } 不然 {
            出版(ORB_ID(key_command), _key_command_pub、 及样品;键);
        }
    }
  5. 制作自己的 uORB 主题订阅器,就像任何订阅器模块示例一样。在本例中,让我们在 (/PX4-Autopilot/src/modules/key_receiver) 目录下创建模型。在该目录下创建三个文件 CMakeLists.txt, key_receiver.cpp, Kconfig 每一个都像下面这样。

    -CMakeLists.txt

    cmake
    px4_add_module(
        模块__密钥接收器
        MAIN 密钥接收器
        stack_main 2500
        堆栈最大值 4000
        SRCS
            key_receiver.cpp
        取决于
    
        )

    -key_receiver.cpp

    #include <px4_platform_common/px4_config.h>;
    #include <px4_platform_common/tasks.h>;
    #include <px4_platform_common/posix.h>;
    #include <unistd.h>;
    #include <stdio.h>;
    #include <poll.h>;
    #include <string.h>;
    #include <math.h>;
    
    #include <uORB/uORB.h>;
    #include <uORB/topics/key_command.h>;
    
    extern "C" __EXPORT int key_receiver_main(int argc, char **argv);
    
    int key_receiver_main(int argc, char **argv)
    {
        int key_sub_fd = orb_subscribe(ORB_ID(key_command));
        orb_set_interval(key_sub_fd, 200); // 将更新速率限制为 200ms
    
        px4_pollfd_struct_t fds[] = {
            { .fd = key_sub_fd,.events = POLLIN }、
        };
    
        int error_counter = 0;
    
        for (int i = 0; i < 10; i++)
        {
            int poll_ret = px4_poll(fds,1,1000);
    
            如果 (poll_ret == 0)
            {
                PX4_ERR("Got no data within a second");
            }
    
            else if (poll_ret < 0)
            {
                if (error_counter < 10 || error_counter % 50 == 0)
                {
                    PX4_ERR("ERROR return value from poll():%d", poll_ret);
                }
    
                error_counter++;
            }
    
            不然
            {
                if (fds[0].revents & POLLIN)
                {
                    struct key_command_s input;
                    orb_copy(ORB_ID(key_command),key_sub_fd,&input);
                    PX4_INFO("Received Char : %c", input.cmd);
                 }
            }
        }
        返回 0;
    }

    -Kconfig

     menuconfig MODULES_KEY_RECEIVER
     bool "key_receiver";
     默认值 n
     ---帮助
     	启用对密钥接收器的支持

    有关更详细的解释,请参阅主题 撰写第一份申请.

  6. 最后,在 default.px4boardPX4-Autopilot/boards/.例如:-对于 Pixhawk 4,在以下代码中添加 PX4-Autopilot/boards/px4/fmu-v5/default.px4board为 SITL 添加以下代码 PX4-Autopilot/boards/px4/sitl/default.px4board

     CONFIG_MODULES_KEY_RECEIVER=y

现在,您已经准备好制作所有作品了!

建筑

为 ROS 构建

  1. 在工作区中输入 柔荑花序.

  2. 在此之前,必须在 (/workspace/src/mavros/mavros/launch) 中设置 "px4.launch"。如下所示编辑 "px4.launch"。如果使用 USB 将计算机与 Pixhawk 连接,则必须设置 "fcu_url",如下图所示。但是,如果使用 CP2102 连接计算机和 Pixhawk,则必须将 "ttyACM0" 替换为 "ttyUSB0"。如果使用 SITL 连接终端,则必须将 "/dev/ttyACM0:57600" 替换为 "udp://:[email protected]:14557"。修改 "gcs_url" 是为了使用 UDP 连接 Pixhawk,因为串行通信无法同时接受 MAVROS 和果壳连接。

  3. 将您的 IP 地址写在 "xxx.xx.xxx.xxx";

    xml
    ...
      <;雅格 名字="fcu_url"; 默认="/dev/ttyACM0:57600"; />;
      <;雅格 名字="gcs_url"; 默认="udp://:[email protected]:14557"; />;
    ...

为 PX4 打造

  1. 清理之前创建的 PX4-Autopilot 目录。在 PX4-自动驾驶仪 目录:

    生产 清洗
  2. 构建 PX4-Autopilot 并上传 照常.

    例如

    • 要为 Pixhawk 4/FMUv5 构建,请在 PX4-Autopilot 目录根目录下执行以下命令:
    生产 px4_fmu-v5_default 上传
    • 在 PX4-Autopilot 目录根目录下执行以下命令(使用 jmavsim 仿真)以构建 SITL:
    生产 px4_sitl jmavsim

运行代码

接下来测试 MAVROS 信息是否发送到 PX4。

运行 ROS

  1. 在终端中输入
    玫瑰发射 马夫罗斯 px4.launch
  2. 在第二个终端运行中:
    游标 酒吧 -r 10 /mavros/keyboard_command/keyboard_sub std_msgs/Char 97
    这意味着将 97 ('a' 以 ASCII 编码) 发布到 ROS 主题 "/mavros/keyboard_command/keyboard_sub",信息类型为 "std_msgs/Char"。"-r 10" 表示以 "10Hz"连续发布。

运行 PX4

  1. 通过 UDP 输入 Pixhawk 果壳。用您的 IP 替换 xxx.xx.xxx.xxx。

    CD PX4-自动驾驶仪/工具
    ./mavlink_shell.py xxx.xx.xxx.xxx:14557 --波特率 57600
  2. 几秒钟后,按 进入 几次。你应该会在终端中看到如下提示:

    nsh>;
    nsh>;

    输入 "key_receiver",运行用户模块。

    nsh> 密钥接收器

检查是否成功接收 a 您的 ROS 主题。