mavlink / mavros

MAVLink to ROS gateway with proxy for Ground Control Station
Other
879 stars 989 forks source link

Play a tune via MAVCMD #1249

Open smartexagro opened 5 years ago

smartexagro commented 5 years ago

I'm trying to play a tune via rosrun command: rosrun mavros mavcmd 258 0 0 0 0 0 0 0

anybody knows which params i need to send?


MAVROS version and platform

ROS: Melodic Ubuntu: 16.04

Autopilot type and version

[ ] ArduPilot [ x] PX4

Version: 3.7.1

vooon commented 5 years ago

MAV_CMD doesn't have such command.

If you want to send PLAY_TUNE, then you have to write a plugin.

AnneWendt commented 3 years ago

Beginner question: now that the plugin exists (see this pull request - thanks @mortenfyhn) what would be the most straightforward way to play a simple tune via mavros?

I am on ROS noetic, Ubuntu 20.04, ArduSub 4.0.2 on Pixhawk1. Buzzer is connected and plays something when the pixhawk starts up. But I can't get it to play anything after that.

I have tried roslaunch mavros apm.launch fcu_url:=udp://:14550@127.0.0.1:14549 and when I do rostopic echo /mavros/state it shows regular messages, so I am fairly confident the connection worked. However, when I try rostopic pub -1 /mavros/play_tune mavros_msgs/PlayTuneV2 "format: 2 tune: '>e16e8e16r16c16e8g4<g4'" nothing happens.

I feel like I am missing a crucial basic step. Any pointer into the right direction would be appreciated. I am still learning.

mortenfyhn commented 3 years ago

No worries, what you're missing might just be to enable the play_tune plugin. When you launch mavros, do you get a long list of plugins saying plugin loaded / blacklisted / similar? It tells you which plugins are enabled. You can add the play_tune plugin to the config file apm_pluginlists.yaml which is read by apm.launch. Hopefully that solves it.

AnneWendt commented 3 years ago

Thank you for your fast reply!

Yep, I get [ INFO] [1620733606.153262125]: Plugin play_tune loaded [ INFO] [1620733606.155413105]: Plugin play_tune initialized

apm_pluginlists.yaml looks like this:

plugin_blacklist:
# common
- actuator_control
- ftp
- safety_area
- hil
# extras
- altitude
- debug_value
- image_pub
- px4flow
- vibration
- vision_speed_estimate
- wheel_odometry

plugin_whitelist: []
#- 'sys_*'
mortenfyhn commented 3 years ago

That's odd. Do you have QGroundControl or something similar running? You can use its "mavlink inspector" to check if you're seeing mavlink PLAY_TUNE_V2 message. Beyond that I think the other maintainers might be better suited to figure this out.

AnneWendt commented 3 years ago

Oh, interesting, it doesn't show up in QGC.

qgc_mavlink_messages

Looks like I will first need to figure out what's going wrong here. Maybe it's an issue with ArduSub.

Oh and thank you very much for your time :-)

mortenfyhn commented 3 years ago

It might be so that it won't show up in QGC even when it works, when I think about it. The message might go straight to the pixhawk, and the pixhawk might not pass it on to QGC.

vooon commented 3 years ago

@mortenfyhn PLAY_TUNE goes strait to FCU link, so it's unlikely to see it on GCS, except if the firmware routes it back. Unfortunately it's not easy to capture that message in mavros v1, only if you put something between FCU and MAVROS to catch packets.

Hmm, you could try to build Wireshark plugin to inspect data (but i don't really know is it still working or not). And since we are dealing with opensource firmware, we could go and see whether ArduSub accepts that message or not :)

vooon commented 3 years ago

https://github.com/ArduPilot/ardupilot/blob/0cd97ce3d8f394e2b853b1f835abf74e6488daf5/libraries/GCS_MAVLink/GCS_Common.cpp#L3494-L3497

And:

https://github.com/ArduPilot/ardupilot/blob/0cd97ce3d8f394e2b853b1f835abf74e6488daf5/libraries/AP_Notify/ToneAlarm.cpp#L450-L469

And:

https://github.com/mavlink/mavros/blob/8b9a32ac323e79cef826ee5f39aeb07a1162d240/mavros_extras/src/plugins/play_tune.cpp#L28-L31

So: FW wants PLAY_TUNE, plugin sends PLAY_TUNE_V2. I think we need to add message selection based on AP type.

AnneWendt commented 3 years ago

Interesting to know, thank you for investigating!

Is there a (beginner-friendly) way to circumvent this issue? Can I help with anything and where would be the most effective place to make the change?

mortenfyhn commented 3 years ago

I can probably extend the plugin to support plain PLAY_TUNE messages. @vooon, what's the policy for API changes? I'm tempted to create a new subscriber, so the plugin reads ~play_tune for mavros_msgs/PlayTune -> mavlink PLAY_TUNE, and ~play_tune_v2 for mavros_msgs/PlayTuneV2 -> mavlink PLAY_TUNE_V2. But that will break the old API, which uses ~play_tune for v2 messages.

Alternatively I can add a parameter that determines if it expects v1 or v2 messages on ~play_tune, and I'll output the matching mavlink message.

vooon commented 3 years ago

@mortenfyhn since we at 1.0 stage, i'd prefer to keep existing api. Also user shouldn't care about witch version of message is sent, so i'd prefer to add param plus detection.

Something like that:

void connection_cb() {
  int new_ver = 0
  if (nh.getParam("message_version", new_ver) {
    // check 1 vs 2
  } 
  if (new_ver == 0) {
    new_ver = m_uas->is_ardupilotmega() ? 1 : 2;
  }

  message_version = new_ver;
}
mortenfyhn commented 3 years ago

@mortenfyhn since we at 1.0 stage, i'd prefer to keep existing api.

:+1:

I'll do roughly as you suggest:

vooon commented 3 years ago

Yes, also i think it's ok to use 0 == auto (v1 for APM / v2 for others).

vooon commented 3 years ago

Ah, also, we should simply convert PlayTuneV2.msg to PLAY_TUNE. Need to check that format == MML (APM's implementation), then do something like that (pseudocode):


PLAY_TUNE pt{};

mavlink::set_string(pt.tune, tune->tune);
mavlink::set_string_z(pt.tune2, tune->tune[pt.tune.size():]);
``
AnneWendt commented 3 years ago

Hi guys, I was just wondering if there were any updates on this topic. This is probably not a top priority but I think it would be pretty neat if this worked as intended. Cheers Anne

mortenfyhn commented 3 years ago

Hi! I would very much like to fix this but I cannot prioritize it, at least not for a while. Have you considered trying to implement the change?

abhi2198 commented 2 years ago

So the issue is that ardupilot accepts only PLAY_TUNE and you are publishing PLAY_TUNE_V2, a solution would be to send the message from mavlink as PLAY_TUNE instead of PLAY_TUNE_V2. You can change the callback function in https://github.com/mavlink/mavros/blob/ros2/mavros_extras/src/plugins/play_tune.cpp as follows,

void callback(const mavros_msgs::PlayTuneV2::ConstPtr& tune)
    {
        auto msg = mavlink::common::msg::PLAY_TUNE{};
        m_uas->msg_set_target(msg);
        // msg.format = tune->format;
        mavlink::set_string_z(msg.tune, tune->tune);
        UAS_FCU(m_uas)->send_message_ignore_drop(msg);
    }

@AnneWendt