Mavros: أرسل رسائل MAVLink إلى QGroundControl

تم إنشاؤها على ١٤ يوليو ٢٠١٦  ·  14تعليقات  ·  مصدر: mavlink/mavros

أهلا!

لدي جهاز محاكاة طائرة ، والذي يرسل بعض معلومات الطيران من خلال موضوعات ROS. أود أن آخذه وأرسله إلى QGroundControl باستخدام MAVLink.

لبدء اختبار كيفية عملها ، حاولت إرسال رسالة بحالة بطارية مزيفة (mavros_msgs / BatteryStatus.msg):

1 - أولاً ، أقوم بتشغيل mavros_node مع gcs_url = udp: //: [email protected] : 14551.
2 - أقوم بتشغيل العقدة الخاصة بي ، والتي من المفترض أن ترسل رسالة البطارية:

#include <ros/ros.h>
#include <mavros_msgs/BatteryStatus.h>

int main(int argc, char *argv[])

{
    ros::init(argc, argv, "battery_node");
    ros::NodeHandle n;
    ros::Publisher battery_pub = n.advertise<mavros_msgs::BatteryStatus>("/mavros/battery", 1000);
    ros::Rate loop_rate(10);

    while (ros::ok())
    {
        mavros_msgs::BatteryStatus baterry_msg;

        baterry_msg.voltage = 5;
        baterry_msg.current = 0.5;
        baterry_msg.remaining = 0.36;

        battery_pub.publish(baterry_msg);

        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

3 - أقوم بتوصيل QGroundControl بـ UDP: 127.0.0.1:14551

... ولا يحدث شيء = /

أنا متأكد من أن الصلة بين mavros و QGC تعمل ، لأنني إذا قمت بتشغيل محاكاة باستخدام MAVProxy على الرغم من 127.0.0.1:14540 ، باستخدام mavros كـ "جسر" ، يتم التعرف على الطائرة.

ما الخطأ الذي افعله؟

أنا أستخدم Ubuntu 14 و ROS Indigo و QGC 2.9.7.

شكرا جزيلا لك مقدما،
بابلو

question

التعليق الأكثر فائدة

ربما يكون من الأفضل أيضًا كتابة gcs_bridge مخصص ، حيث يوجد لديك فئة MAVConnInterface ، حيث يمكنك إرسال رسالتك:

auto gcs_link = MAVConnInterface::open_url("udp-b://@");

mavlink::common::msg::HEARTBEAT hb{};
// fill hb

gcs_link->send_message_ignore_drop(hb);

ال 14 كومينتر

sys_status : كما ترى ، فإن mavros هي _publisher_ وليست مشتركًا.

مرحبا vooon ،

شكرا لاجابتك. إذا فهمت ذلك جيدًا ، لا يمكن إرسال هذه الرسالة ، ويتم استلامها وعرضها فقط في ROS ، هل أنا على صواب؟

هل يمكنني إذن استخدام _mavlink / to_ لإرسال هذه الرسائل؟
كيف يمكنني فعل ذلك؟

شكرا لك مرة أخرى!

يرسل mavlink/to الرسالة إلى FCU وليس GCS.

ولكن يمكنك استخدام عقدة gcs_bridge وموضوع mavlink/from .

أهلا مرة أخرى،

حسنًا ، لقد غيرت الرمز بحيث يرسل رسالة بسيطة حول نبضات القلب:

#include <ros/ros.h>
#include <mavros_msgs/Mavlink.h>

int main(int argc, char **argv){

    ros::init(argc, argv, "hertbeat_publisher");
    ros::NodeHandle n;

    ros::Publisher example_pub = n.advertise<mavros_msgs::Mavlink>("/mavlink/from", 1000);
    ros::Rate loop_rate(1); // 1 Hz

    mavros_msgs::Mavlink mavlink_msg;

    mavlink_msg.len = 2;
    mavlink_msg.sysid = 1;
    mavlink_msg.compid = 1;
    mavlink_msg.msgid = 0;

    std::vector<long unsigned int> payload64(7, 0);

    mavlink_msg.payload64 = payload64;

    while (ros::ok())
    {
        mavlink_msg.header.stamp = ros::Time::now();
        if (mavlink_msg.seq < 255){
            mavlink_msg.seq++;
        }
        else {mavlink_msg.seq = 0;}

        // publish message
        example_pub.publish(mavlink_msg);

        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

1 - قمت بتشغيل mavros_node مع fcu_url = udp: //: 14540 @ و gcs_url = udp: //: [email protected] : 14551 ، الحصول على:

[ INFO] [1468659493.280504313]: FCU URL: udp://:14540@
[ INFO] [1468659493.289025098]: udp0: Bind address: 0.0.0.0:14540
[ INFO] [1468659493.289457240]: GCS URL: udp://:[email protected]:14551
[ INFO] [1468659493.289691565]: udp1: Bind address: 0.0.0.0:14570
[ INFO] [1468659493.289824558]: udp1: Remote address: 127.0.0.1:14551
...
[ INFO] [1468659494.906066742]: MAVROS started. MY ID 1.240, TARGET ID 1.1

2 - قمت بتشغيل gcs_bridge باستخدام gcs_url: = 'udp: //@127.0.0.1' ، والحصول على:

[ INFO] [1468659758.392659411]: udp0: Bind address: 0.0.0.0:14555
[ INFO] [1468659758.392800665]: udp0: Remote address: 127.0.0.1:14550

3 - أقوم بتشغيل العقدة أعلاه ، والنشر في / mavlink / من 1 هرتز.
4 - أقوم بتوصيل QGroundControl باستخدام UDP 127.0.0.1:14550 ، باستخدام معرف النظام 1

... ومرة ​​أخرى مفتش MAVLink فارغ.

في البداية ، لم يحدث أي شيء ، ولكن في مرحلة ما ، ألقى QGroundControl هذا الخطأ:

يوجد إصدار MAVLink أو عدم تطابق معدل الباود. يرجى التحقق مما إذا كانت معدلات البث بالباود الخاصة بـ QGroundControl والطيار الآلي الخاص بك هي نفسها.

أعتقد أن QGC يغير بطريقة ما منفذ UDP في مرحلة ما قبل هذا الخطأ.

ما الخطأ الذي افعله؟

شكرا!

أ) لا تستخدم gcs_url من mavros! يجب عليك الاتصال بـ gcs_bridge !
ب) رمز غير صالح لملء Mavlink.msg. يجب أن يكون شيئًا مثل هذا:

mavlink::common::msg::HEARTBEAT hb{};
...

mavlink::mavlink_message_t msg;
mavlink::MsgMap map(msg);

hb.serialize(map);
mavlink::finalize_message_buffer(&msg, sysid, compid, ...);

mavros_msgs::Mavlink ml;
mavros_msgs::mavlink::convert(msg, ml);

يرى:

أهلا!

شكرا! لقد نجحت في النهاية. لقد استخدمت فصولًا مختلفة ، لأنني أستخدم Indigo. أترك الكود هنا ، في حال تساءل شخص آخر عن كيفية القيام بذلك بالضبط. أبعث برسالة نبضات القلب والارتفاع وأستقبلهما في QGroundControl:

1- قم بتشغيل عقدة mavros مع fcu_url = udp: //: 14540 @ and gcs_url = udp: //: [email protected] : 14551.
2- إطلاق gcs_bridge باستخدام gcs_url: = udp: //@127.0.0.1: 14560.
3- إطلاق هذه العقدة:

#include <ros/ros.h>
#include <mavconn/interface.h>
#include <mavros_msgs/Mavlink.h>
#include <mavros_msgs/mavlink_convert.h>

// General parameters
uint8_t system_id = 1;
uint8_t component_id = 1;
uint8_t type = 1;
uint8_t autopilot = 0;
uint8_t base_mode = 128;
uint32_t custom_mode = 0;
uint8_t system_status = 0;

// Parameters of the altitude message
float alt_monotonic = 10.0;
float alt_amsl = 100;
float alt_local = 10.0;
float alt_relative = 10.0;
float alt_terrain = 10;
float bottom_clearance = 0;

int main(int argc, char **argv){

    // Create heartbeat message
    mavlink_message_t msg_heartbeat;
    mavlink_msg_heartbeat_pack(system_id, component_id, &msg_heartbeat, type, autopilot, base_mode, custom_mode, system_status);

    mavros_msgs::Mavlink ml_heartbeat;
    mavros_msgs::mavlink::convert(msg_heartbeat, ml_heartbeat);

    // Create altitude message
    mavlink_message_t msg_altitude;
    mavros_msgs::Mavlink ml_altitude;

    ros::init(argc, argv, "telemetry_publisher");
    ros::NodeHandle n;

    ros::Publisher example_pub = n.advertise<mavros_msgs::Mavlink>("/mavlink/from", 1000);
    ros::Rate loop_rate(1); // 1 Hz

    while (ros::ok())
    {
        uint64_t time_stamp = ros::Time::now().nsec;

        // Finish altitude message
        mavlink_msg_altitude_pack(system_id, component_id, &msg_altitude, time_stamp, alt_monotonic, alt_amsl, alt_local, alt_relative, alt_terrain, bottom_clearance);
        mavros_msgs::mavlink::convert(msg_altitude, ml_altitude);

        // Publish messages
        example_pub.publish(ml_heartbeat);
        example_pub.publish(ml_altitude);

        ros::spinOnce();
        loop_rate.sleep();
    }
    return 0;
}

4- قم بتشغيل QGroundControl وتكوين الاتصال على 127.0.0.1:14560

إذا فتحت MavLink Inspector ، فسترى نبضات القلب ورسالة الارتفاع عند ~ 1 هرتز تقريبًا.

أحاول القيام بذلك ، ولكن أخطأت ، لا أستطيع حقًا أن أفهم لماذا ، هل يمكن لأي شخص مساعدتي؟
يجب تضمين وظيفة mavlink_msg_heartbeat_pack عند # تضمينلكنها لم ...
قد أكون مخطئا في cmake؟

#include "ros/ros.h"
#include <mavros_msgs/mavlink_convert.h>
#include <mavconn/interface.h>

int main(int argc, char **argv)
{
    ros::init(argc, argv, "talker");
    ros::NodeHandle n;
    ros::Publisher pub = n.advertise<mavros_msgs::Mavlink>("/mavlink/from", 1000);
    ros::Rate loop_rate(10);

    uint8_t system_id = 1;
    uint8_t component_id = 1;
    uint8_t type = 1;
    uint8_t autopilot = 0;
    uint8_t base_mode = 128;
    uint32_t custom_mode = 0;
    uint8_t system_status = 0;
    mavlink_message_t msg;
    mavlink_msg_heartbeat_pack(system_id, component_id, &msg, type, autopilot, base_mode, custom_mode, system_status);
  return 0;
}
cmake_minimum_required(VERSION 2.8.3)
project(talker)

find_package(catkin REQUIRED COMPONENTS mavros mavros_msgs mavlink)
catkin_package()
include(EnableCXX11)
include(MavrosMavlink)
include_directories(
  ${catkin_INCLUDE_DIRS}
  ${mavlink_INCLUDE_DIRS}
)

add_executable(talker talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})

خطأ: لم يتم التصريح عن 'mavlink_message_t' في هذا النطاق
mavlink_message_t msg ؛
خطأ: لم يتم التصريح عن "mavlink_msg_heartbeat_pack" في هذا النطاق
mavlink_msg_heartbeat_pack (معرف_النظام ، معرف_المكوّن ، & msg ، النوع ، الطيار الآلي ، الوضع الأساسي ، الوضع المخصص ، حالة النظام) ؛

shawinmihail ما هو إصدار مافروس؟ 0.18+ سيشمل فقط mavlink_helpers.h و C ++ 11 lib.

لقد وجدت حلا لمشكلتي. من المحتمل أن mavros v0.18 + يستخدم رؤوس mavlink v2.0 فقط. لإنشاء أي رسالة يجب أن نستخدم MsgMap.serialize () بدلاً من msg_name_pack ()

    mavlink::mavlink_message_t msg;
    mavlink::MsgMap map(msg);
    mavlink::groupcontrol::msg::GROUP_COEFFS_PART1 msgPart1 //my custom msg;

    msgPart1.kc = kc;
    msgPart1.ks = ks;
        //........................... - fill msg

         msgPart1.serialize(map);
    map.reset();
    auto mi = msgPart1.get_message_info();
    mavlink::mavlink_finalize_message(&msg, system_id, component_id, mi.min_length, mi.length, mi.crc_extra);

    mavros_msgs::Mavlink mavrosMsg;
    mavros_msgs::mavlink::convert(msg, mavrosMsg);

ربما يمكن أن يساعد شخص ما. إذا كنت تعرف طريقة أفضل ، يرجى كتابتها.
شكرا على التلميح.

Message::serialize() يفعل MsgMap::reset() ، لا تسميها مباشرة! قد يكسر الرسالة.

ربما يكون من الأفضل أيضًا كتابة gcs_bridge مخصص ، حيث يوجد لديك فئة MAVConnInterface ، حيث يمكنك إرسال رسالتك:

auto gcs_link = MAVConnInterface::open_url("udp-b://@");

mavlink::common::msg::HEARTBEAT hb{};
// fill hb

gcs_link->send_message_ignore_drop(hb);

vooon ، شكرا على التعليقات. أجد أن الحل الخاص بي لا يعمل مع بروتوكول mavlink v1.0 بشكل صحيح. الآن أقوم بصنع واختبار واحدة جديدة ، إنها تعمل!

#include "ros/ros.h"
#include <mavros_msgs/mavlink_convert.h>
#include <mavconn/interface.h>
#include <iostream>
#include <mavlink/v2.0/mavlink_helpers.h>


float kc = 0.0f; /*< gravity coeff */
float ks = 0.0f; /*< repulsive coeff */
float ka = 0.0f; /*< speed alignment coeff */
float kp = 0.0f; /*< chasing coeff */
float km = 0.0f; /*< waypoint gravity coeff */
float kh = 0.0f; /*< rotate speed coeff */
float vmax = 0.0f; /*< max autopilot velocity */
float rn = 0.0f; /*< search radius of groupmate  */
float rs = 0.0f; /*< repulsiveOn radius */
float rm = 0.0f; /*< getting waypoint radius */
float rmb = 0.0f; /*< change gravity law radius */

void packMavlinkMessage(const mavlink::Message& mavMsg, mavros_msgs::Mavlink &rosMsg)
{
    mavlink::mavlink_message_t msg;
    mavlink::MsgMap map(msg);
    mavMsg.serialize(map);
    auto mi = mavMsg.get_message_info();

    mavlink::mavlink_status_t *status = mavlink::mavlink_get_channel_status(mavlink::MAVLINK_COMM_0);
    status->flags |= MAVLINK_STATUS_FLAG_OUT_MAVLINK1;
    mavlink::mavlink_finalize_message_buffer(&msg, 1, 1, status, mi.min_length, mi.length, mi.crc_extra);

    mavros_msgs::mavlink::convert(msg, rosMsg);
}

void mavlinkCallback(const mavros_msgs::Mavlink& msg)
{
    mavlink::mavlink_message_t mavMsg;
    mavros_msgs::mavlink::convert(msg, mavMsg);

    if(mavMsg.msgid == mavlink::groupcontrol::msg::SET_GROUP_PARAMS::MSG_ID)
    {
        ROS_WARN("SET GROUP_PARAMS");
        mavlink::MsgMap map(mavMsg);
        mavlink::groupcontrol::msg::SET_GROUP_PARAMS setParamsMsg;
        setParamsMsg.deserialize(map);

        std::cout << setParamsMsg.kc;
    }
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "talker");
    ros::NodeHandle n;
    ros::Publisher pub = n.advertise<mavros_msgs::Mavlink>("/mavlink/from", 1000);
    ros::Subscriber sub = n.subscribe("mavlink/to", 1000, mavlinkCallback);
    ros::Rate loop_rate(10);

    ROS_INFO("%s", "Talker started");

    mavlink::groupcontrol::msg::GROUP_PARAMS msgPart1;
    msgPart1.kc = kc;
    msgPart1.ks = ks;
    msgPart1.ka = ka;
    msgPart1.kp = kp;
    msgPart1.km = km;
    msgPart1.kh = kh;
    msgPart1.vmax = vmax;
    msgPart1.rn = rn;
    msgPart1.rs = rs;
    msgPart1.rm = rm;
    msgPart1.rmb = rmb;

    while (ros::ok())
    {
        mavros_msgs::Mavlink mavrosMsg;
        packMavlinkMessage(msgPart1, mavrosMsg);
        pub.publish(mavrosMsg);
        ros::spinOnce();
        loop_rate.sleep();
    }


  return 0;
}

قد يكون شخص ما يمكن أن يساعدني والكتابة
كيف يمكنني أن أفعل الشيء نفسه من بيثون على سبيل المثال
إنشاء mavlink msg وتحويله إلى mavros msg؟

ربما يكون من الأفضل أيضًا كتابة gcs_bridge مخصص ، حيث يوجد لديك فئة MAVConnInterface ، حيث يمكنك إرسال رسالتك:

auto gcs_link = MAVConnInterface::open_url("udp-b://@");

mavlink::common::msg::HEARTBEAT hb{};
// fill hb

gcs_link->send_message_ignore_drop(hb);

يمكن أن ترسل هذه الطريقة ببساطة رسالة مخصصة ، ولكن هل هناك أي خطر؟ تضمين التغريدة

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

mohand150 picture mohand150  ·  5تعليقات

TeixeiraRafael picture TeixeiraRafael  ·  4تعليقات

trishantroy picture trishantroy  ·  10تعليقات

L4ncelot picture L4ncelot  ·  5تعليقات

fionachui picture fionachui  ·  9تعليقات