Error while data type conversion from "Unsigned char" to "Const mavlink" {aka mavlink message type}

Hello @LorenzMeier, @Jaeyoung-Lim, @JonasVautherin, @JulianOes.
I have tried the procedure to create custom mavlink message and send it from MAVROS to PX4 simualtion instance from “Sending Custom Messages from MAVROS · PX4 Developer Guide”.
I face the following error when i build MAVROS again after creating files for custom message. The error is is the line highted in the image below:

The error screen shot in terminal is shown below:


Now, I have searched for way to resolve this error but unable to do. Please tell me how to do this conversion from std_msgs/Char type to mavlink_message_t. Also please give some insight on mavlink_message_t (what type of data is it and any useful info).

Ya, that’s not gonna work an unsigned char can not become a mavlink_message.
That example in the docs seems to be wrong.
Try something like this:

  void send_to_pixhawk(char cmd)
    {
        mavlink_message_t msg;
        mavlink_msg_key_command_pack_chan(UAS_PACK_CHAN(uas), &msg, cmd);
        UAS_FCU(uas)->send_message(&msg);
    }

    void keyboard_cb(const std_msgs::Char::ConstPtr &req)
    {
        std::cout << "Got Char : " << req->data <<  std::endl;
        send_to_pixhawk(req->data);
    }

From:

Hello @jimdgit, @TSC21, I followed what you told, i got the following error:

My keyboard_command.cpp file is as follows:

 #include <mavros/mavros_plugin.h>
 #include <pluginlib/class_list_macros.h>
 #include <iostream>
 #include <std_msgs/Char.h>
//#include <std_msgs/String.h>
//#include <mavlink/v2.0/mavlink_msg_key_command.h>

 namespace mavros {
 namespace extra_plugins{

 class KeyboardCommandPlugin : public plugin::PluginBase {
 public:
     KeyboardCommandPlugin() : PluginBase(),
         nh("~keyboard_command")

    { };

     void initialize(UAS &uas_)
     {
         PluginBase::initialize(uas_);
         keyboard_sub = nh.subscribe("keyboard_sub", 10, &KeyboardCommandPlugin::keyboard_cb, this);
     };

     Subscriptions get_subscriptions()
     {
         return {/* RX disabled */ };
     }

 private:
     ros::NodeHandle nh;
     ros::Subscriber keyboard_sub;
     UAS *uas;

    void send_to_pixhawk(char cmd)
    {
        mavlink_message_t msg;
        mavlink_msg_key_command_pack_chan(UAS_PACK_CHAN(uas), &msg, cmd);
        UAS_FCU(uas)->send_message(&msg);
    }

    void keyboard_cb(const std_msgs::Char::ConstPtr &req)
     {
         std::cout << "Got Char : " << req->data <<  std::endl;
         send_to_pixhawk(req->data);
         //UAS_FCU(m_uas)->send_message_ignore_drop(req->data);
     }
 };
 }   // namespace extra_plugins
 }   // namespace mavros

PLUGINLIB_EXPORT_CLASS(mavros::extra_plugins::KeyboardCommandPlugin, mavros::plugin::PluginBase)

Any suggestion to solve this, is there any header file missing, mavlink_message_t is not being recognized.

try including:
mavlink.h
But look this code was bugged from the start and I can’t find the source file for it
Also you seem new to c++ so this will no doubt be a heavy lift.
If it does not work I will have no idea why, I just know you can’t cast a char to a struct.
Perhaps @JulianOes will jump in who has much more knowledge about mavlink.
Really that example should be updated or removed.

hello @jimdgit, thanks for your quick replies.
I would like to say that mavlink_message_t struct is already included via mavros_plugin.h in the file keyboard_command.cpp. I would like to include @JulianOes, @Vladimir_Ermakov o look into the code for a second. My plugin file looks like:

     #include <mavros/mavros_plugin.h>
     #include <pluginlib/class_list_macros.h>
     #include <iostream>
     #include <std_msgs/Char.h>
     
     namespace mavros {
     namespace extra_plugins{

     class KeyboardCommandPlugin : public plugin::PluginBase {
     public:
     KeyboardCommandPlugin() : PluginBase(),
         nh("~keyboard_command")

    { };

     void initialize(UAS &uas_)
     {
         PluginBase::initialize(uas_);
         keyboard_sub = nh.subscribe("keyboard_sub", 10, &KeyboardCommandPlugin::keyboard_cb, this);
     };

     Subscriptions get_subscriptions()
     {
         return {/* RX disabled */ };
     }

     private:
     ros::NodeHandle nh;
     ros::Subscriber keyboard_sub;
     //UAS *uas;

    void send_to_pixhawk(char cmd)
    {
        mavlink_message_t msg;
        mavlink_msg_key_command_pack_chan(UAS_PACK_CHAN(uas), &msg, cmd);
        UAS_FCU(uas)->send_message(&msg);
    }

    void keyboard_cb(const std_msgs::Char::ConstPtr &req)
     {
         std::cout << "Got Char : " << req->data <<  std::endl;
         send_to_pixhawk(req->data);
         //UAS_FCU(m_uas)->send_message_ignore_drop(req->data);
     }
     };
     }   // namespace extra_plugins
     }   // namespace mavros

    PLUGINLIB_EXPORT_CLASS(mavros::extra_plugins::KeyboardCommandPlugin, mavros::plugin::PluginBase)

and the error that i encounter is shown as:

here __mavlink_messageis defined in file catkin_ws/devel/include/mavlink/v2.0/mavlink_type.h which is included in mavros_plugins.h at the top of plugin file. Can someone tell me why the error mavlink_message_t not declared in this scope appearing when already its header is included?
Moreover, i would like to point out that the function UAS_PACK_CHAN() in send_to_pixhawk function in keyboard_command.cpp is present no where in mavros, mavlink or any package in ROS installtion directory /opt/ros/melodic. Can you tell me what is it doing and where is it defined in mavlink or mavros or any related package.
Any help is appreciated.

As I have tried to explain this example is obsolete.
Please choose another example from:


as your starting point.
They will at least build and if you study them, you see examples of what you need.

OKay, thanks @jimdgit, i will try some of them suggested by you. :slightly_smiling_face:

Also look at:

I am also following the same example and receiving the same error message as OP. Has there been any movement in correcting the root cause and pushing the fix? A working end-to-end tutorial is extremely valuable.

I believe I’ve identified the problem with this example. The current version of the example is not packaging the input into the KEY_COMMAND message the user created in the common.xml file. Using the following definition of the keyboard_cb function compiles successfully.

   void keyboard_cb(const std_msgs::Char::ConstPtr &req)
 {
     std::cout << "Got Char : " << req->data <<  std::endl;
     
     mavlink::common::msg::KEY_COMMAND kc {};
     kc.command = req->data;
     
     UAS_FCU(m_uas)->send_message_ignore_drop(kc);
 }

I will keep working on it and post my progress as I kick the tires.

1 Like

I now have the complete functionality working. The current version of the tutorial is way out of date. I found the following issues while working through it:

  • The callback function ‘keyboard_cb’ is missing steps to create a msg and add data to the field (see above post)
  • The CMake file for the keyboard module has “platforms__common” as a dependency. I could not get it to compile with it included. Removing it worked fine.
  • There is no “timestamp” field in the key_command msg template. This is required for an assertion check to pass. This field is also used by a later function in the current version of the tutorial so it is a clear omission. This field also needs to be defined in the xml files for PX4 and MAVROS.
  • The names of the included header files for the PX4 side of the implementation look to be for an older version. For example include <px4_config.h> did not work but include <px4_platform_common/config.h> did.
  • Targeting a test deployment for SITL is an easier test than assuming access to hardware. I was able to get it running with jamvsim SITL.
  • The template used for the PX4 key_receiver module is out of date. The “while(true)” is gross.
5 Likes

Hey Ryan !
I’m having the same problem now and I’m trying to solve it.

Can you please tell us how did you fix all these issues ?

Hey Yfrikha, which problem are you having? The bulleted list I posted should capture all the issues I came across while troubleshooting. You should be able to follow the current buggy version of the tutorial and reference my list to see which steps and files should be modified to get it working. Let me know if something’s not clear enough and I’ll see what I can do to help you out.

Yes yes !
I’ve spent some time fixing these issues too. I just felt lost at first so I needed some guidance.
I solved the problem already.
Thank you !

Hey Ryan !
I also encountered the same problem when doing this experiment. It has been solved with your help. Thank you very much, but in the last step, I checked my subscription module and found that there was no data. What is the possible reason?

Hi,
I can’t compile Pixhawk code when I add a new message following the same tutorial.
https://docs.px4.io/master/en/ros/mavros_custom_messages.html
The error I get is as follows: “No ‘timestamp’ field found in key_command msg definition!”.
Could this example in documentation be updated so that it compiles?

Really helpful post.
Is there any newer template somewhere for PX4 key_receiver like messages?

Hi Ryan,

This is very helpful.
Reference that I am following: Sending a Custom Message from MAVROS to PX4 | PX4 User Guide

I am facing the following issue while building PX4. Please help! I am new to PX4.

  • Ubuntu: 20.04
  • ROS: Neotic

And I did not find “include” directory in mavlink which was mentioned in the above reference.

./…/src/modules/mavlink/mavlink_receiver.cpp: In member function ‘void MavlinkReceiver::handle_message(mavlink_message_t*)’:
…/…/src/modules/mavlink/mavlink_receiver.cpp:270:7: error: ‘MAVLINK_MSG_ID_KEY_COMMAND’ was not declared in this scope;

@Ryan1 Hi Ryan, thanks for the great post and comments! Would you be interested in updating the documentation so that people can benefit from your experience?