Open smartexagro opened 5 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.
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.
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_*'
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.
Oh, interesting, it doesn't show up in QGC.
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 :-)
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.
@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 :)
And:
And:
So: FW wants PLAY_TUNE, plugin sends PLAY_TUNE_V2. I think we need to add message selection based on AP type.
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?
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.
@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 since we at 1.0 stage, i'd prefer to keep existing api.
:+1:
I'll do roughly as you suggest:
m_uas->is_ardupilotmega() == true
, then use v1.Yes, also i think it's ok to use 0 == auto (v1 for APM / v2 for others).
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():]);
``
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
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?
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
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