Issue "AP: ServoRelayEvent:"

Hi,
I’m trying to use Python script with SITL and MAVPROXY and I’ve got “AP: ServoRelayEvent:” issue when using this script.
I already tried to find a solution to a “AP: ServoRelayEvent:” issue in the Forum, but to be honest I didn’t understand the answers recieved (and I try for weeks to understand ;-)), so maybe you as Mavproxy experts can give any help

https://discuss.ardupilot.org/t/mavproxy-sitl-issue-with-python-script-error-servorelayevent-channel-is-already-in-use/104444

  • If I’m sending directly to Mavproxy servos commands like “RC 3 1800” it works fine
  • If I’m doing it with the script I’ve got the error message on Mavproxy

servorelayevent channel 3 is already in use

AP: ServoRelayEvent: Channel 2 is already in use
AP: ServoRelayEvent: Channel 1 is already in use
AP: ServoRelayEvent: Channel 3 is already in use

The RC commands in the Python script :

master.mav.command_long_send(
    master.target_system,
    master.target_component,
mavutil.mavlink.MAV_CMD_DO_SET_SERVO,
    0, # confirmation
    2, # param1
    1500, # param2
    0, # param3
    0, # param4
    0, # param5
    0, # param6
    0) # param7

master.mav.command_long_send(
    master.target_system,
    master.target_component,
mavutil.mavlink.MAV_CMD_DO_SET_SERVO,
    0, # confirmation
    1, # param1
    1500, # param2
    0, # param3
    0, # param4
    0, # param5
    0, # param6
    0) # param7


master.mav.command_long_send(
    master.target_system,
    master.target_component,
mavutil.mavlink.MAV_CMD_DO_SET_SERVO,
    0, # confirmation
    3, # param1
    1800, # param2
    0, # param3
    0, # param4
    0, # param5
    0, # param6
    0) # param7

I’ve checked in the SITL parameters but didn’t find anything.
In the MAVPROXY doc there’s something about the module “Relay Management” I don’t know if it can help
https://ardupilot.org/mavproxy/docs/modules/relay.html

If you had this kind of issue before and find a solution or can help, many thanks !
Nico

Hello @Nicolas_T,
I think it’s not clear want you want to achieve:

  1. If you want to move a servo (servos are AP output) it should be ok to send the mavlink command MAV_CMD_DO_SET_SERVO. The error you’re receiving is documented in the mavlink servo doc (check the note).
  2. What you’re doing with mavproxy commands like RC 3 1800 is like moving a stick or pressing a button on your RC controller, so you’re setting an AP input. This is a quite important difference to know and it’s kind of explained here. If that’s what you want to achieve you should send the mavlink message RC_CHANNELS_OVERRIDE.
1 Like

Hi Luca,
Many thanks for these explanations.
You’re right, these 2 concepts “INPUT” and “OUTPUT” were not clear in my mind, now it’s better.

MAV_CMD_DO_SET_SERVO : I check deeply this part, with the note about “SERVOx_FUNCTION parameter value” and I didn’t succed, I’ve check the config and tried to modify it in MP but it didn’t work. In my understanding finally not a problem, because it seems related to Mission Planner and my goal is to only use Mavproxy as GCS and SITL for testing and building my scripts before flights. It was really easy to use in a Python script but the error message “AP: ServoRelayEvent: Channel 2 is already in use” stopped me a long time (and still today)

mavproxy commands like RC 3 1800 : I’ve checked deeply for this one as well - maybe not deeply enough - so in the page “Autopilot Inputs and Outputs” it’s about “Control Inputs” if I’m right ? I need to try “RC_CHANNELS_OVERRIDE” now and I’ll update this post later.

Something else maybe you can help me to understand : in a past post, @khancyr asked me to use “mavproxy_rc.py” but I didn’t understand : do I have to use this script in mine ? The commands in it seems to be like “rc 3 1800” so similar to one of your answer above.

Many thanks anyway for your help
Nico

Great that you better understand that concepts, but now that you understood them what do you want to achieve with your Python script? Do you want to control the RC inputs, like you do with your transmitter or mavproxy rc chan pwm command? Do you want to move a servo output connected to ArduPilot? Do you want to do both?

mavproxy rc chan pwm command , like if it’s the pilot who moves the sticks.

The goal is to build a script with “acro” commands. I don’t want to use LUA because python’ll give me the ability in the future to introduce new libraries.
These commands in the script I’ve got in mind:

  • Arm/mode manual
  • Climb to altitude 50m
  • when altitude 50m, follow these commands: (pitch) rc 2 1500 + (roll) rc 1 1500 + (throttle) rc 3 1800
  • when 270° on the compass, these commands : rc 2 1800 + rc 1 1000 + rc 3 1500
    (it’s a wing, no rudder, so “rc 4” for the yaw is not needed)

Firstable, I need to have the right python script fully readable by Mavproxy, and after that the conditions in Python “altitude 50m” “270° compass”

That’s the plan

If the goal is to command the plane attitude or position I think the right approach is not to give some rc input, but to set guided mode and send some attitude or position target using mavlink messages.
Is your final goal to just move the plane to target positions or do you want to perform acrobatics?

The altitude needs to be a condition for next set of commands, not the final goal.

In the meantime I tried that, in Mavproxy:

MANUAL> long MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE 1500 1500 1800 0 0 0 0 0

wich means in my understanding

(pitch) rc 2 1500
(roll) rc 1 1500
(throttle) rc 3 1800

Nothing happen in Maxproxy, I’ve got an ack and that’s all, so maybe I’m wrong in using “RC CHANNELS OVERRIDE”

Got MAVLink msg: COMMAND_ACK {command : 70, result : 3, progress : 0, result_param2 : 0, target_system : 255, target_component : 230}

And I tried in a test.py, no result from Mavproxy

master.mav.command_long_send(
    master.target_system,
    master.target_component,
mavutil.mavlink.MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE,
    0, # confirmation
    1500, # param1
    1500, # param2
    1800, # param3
    0, # param4
    0, # param5
    0, # param6
    0, # param7
    0) # param8

I’m trying to help you here, but you’re not answering my questions: what is your final goal? Maybe using the rc override function is not the best solution if you want to set the drone position or attitude (the roll, pitch and yaw angles, not the altitude).
By the way in mavlink there is a difference between commands and messages, as explained in this note.
RC_CHANNELS_OVERRIDE is a mavlink message, so to send it in mavproxy:

  1. load the mavproxy message module
    module load message
  2. send the message
    message RC_CHANNELS_OVERRIDE 1 0 1500 1500 1800 0 0 0 0 0

You should send the message at least every second.

Hi Luca,

Sorry for my misunderstanding, it’s ATTITUDE I’m looking for. (Altitude trigger 'll be something else to add later in my script)
I tried that yesterday evening with RC_CHANNELS_OVERRIDE (I found this example below in the forum) , and effectively it works but I feel that it’s like giving a single “pulse” on a stick with a finger so it doesn’t keep the command more than a few second:

def set_rc_channel_pwm3(channel_id, pwm=1500):
      if channel_id < 1 or channel_id > 18:
        print("Channel does not exist.")
        return
    rc_channel_values = [65535 for _ in range(18)]
    rc_channel_values[channel_id - 1] = pwm
    master.mav.rc_channels_override_send(
        master.target_system,                
        master.target_component,             
        *rc_channel_values)               

set_rc_channel_pwm3(3, 1800)

So maybe “OUTPUT” and direct action on the servo is the better way with " MAV_CMD_DO_SET_SERVO" but like I wrote before, I tried several times and I’ve got the blocking messages on Mavproxy " “AP: ServoRelayEvent: Channel 2 is already in use ”"
In the note in “https://ardupilot.org/dev/docs/mavlink-move-servo.html” I tried to modify “SERVOx_FUNCTION parameter value” but it’s related at MP in my understanding and not at a system like mine Mavproxy+SITL, so modifying “SERVOx FUNCTION” in MP parameters didn’t work , and I didn’t find the way to do it in Mavproxy.

And again many thanks for your help
Nico

If you want to use ArduPilot you must let AP takes care of the output, definitely for the main output (throttle, elevator, aileron and rudder).
I think for your goal on ArduPlane you should use the RC_CHANNELS_OVERRIDE with a function similar to the one you posted. Maybe you add as arguments all the channel you want to control and you simply call the function at the desired frequency (at least 1 Hz).

I’ll follow this way, and try to adapt the frequency of the commands.
I know that there is some particular docs on “LUA for Acrobatics” that can fit my needs but LUA’ll not give me the possibility to add external librairies like I can do with Python.
But, if I can’t go forward I’ll use LUA for a brief time and work on my Python script in parallel, to not staying blocked.

Thanks Luca, your help helps a lot!

Bye
Nico

1 Like