Pymavlink motor test

I am trying to make a pymavlink script that would test all the motors of my drones. I have one bluerobotics bluerov2 and and small usv with two motors with ardurover.
I tryied to use master.mav.command_long_send messages, ether in pwm or percentage of throttle but it never worked as expected.

Did anyone ever succeeded making motor tests with pymavlink ?

I tried to connect to the drone and set 20% of throttle for 2s.



#!/usr/bin/env python3

"""

Script simple pour tester tous les moteurs d'un drone ArduSub

Se connecte en UDP sur le port 14550 et teste chaque moteur à 20% pendant 2s

"""




from pymavlink import mavutil

import time

import sys




# Configuration

UDP_PORT = 14550

THROTTLE_POURCENTAGE = 20

DUREE_TEST = 2  # secondes

PAUSE_ENTRE_MOTEURS = 0.5  # secondes




def connecter_drone():

    """Se connecte au drone via UDP"""

    print("Connexion au drone via UDP...")

    print(f"Port: {UDP_PORT}")

    

    try:

        master = mavutil.mavlink_connection(f"udpin:0.0.0.0:{UDP_PORT}")

        print("Attente du heartbeat...")

        master.wait_heartbeat(timeout=10)

        

        target_system = master.target_system

        print(f"✓ Connecté au système {target_system}")

        return master, target_system

        

    except Exception as e:

        print(f"✗ Erreur de connexion : {e}")

        sys.exit(1)




def tester_moteur(master, target_system, numero_moteur, throttle_pourcentage, duree):

    

    # Calcul PWM: 1500 (neutre) + pourcentage * 4

    throttle_pwm = 1500.0 + (throttle_pourcentage * 4.0)

        

    while master.recv_match(type='COMMAND_ACK', blocking=False, timeout=0.1):

        pass

    

    # Envoi de la commande de test moteur

    master.mav.command_long_send(

        target_system,

        master.target_component,

        mavutil.mavlink.MAV_CMD_DO_MOTOR_TEST,

        0,

        float(numero_moteur - 1),  # ArduSub utilise 0-7, on envoie donc n-1

        float(mavutil.mavlink.MOTOR_TEST_THROTTLE_PWM),

        float(throttle_pwm),

        float(duree),

        float(1),

        float(mavutil.mavlink.MOTOR_TEST_ORDER_BOARD),

        float(0)

    )

    

    # Attente de l'ACK

    timeout_start = time.time()

    while time.time() - timeout_start < 3:

        msg = master.recv_match(blocking=True, timeout=0.5)

        if msg and msg.get_type() == 'COMMAND_ACK':

            if msg.command == mavutil.mavlink.MAV_CMD_DO_MOTOR_TEST:

                if msg.result == mavutil.mavlink.MAV_RESULT_ACCEPTED:

                    print("✓")

                    return True

                else:

                    print(f"✗ (code: {msg.result})")

                    return False

    

    print("⚠ (pas de confirmation)")

    return False




def main():

   

    # Connexion

    master, target_system = connecter_drone()

    

    # Confirmation

    print("\n⚠️  ATTENTION: Assurez-vous que les hélices sont retirées!")

    reponse = input("\nLancer le test de tous les moteurs ? (o/n): ")

    

    if reponse.lower() != 'o':

        print("Test annulé.")

        master.close()

        return

    

    # Compte à rebours

    print("\nDémarrage dans 3 secondes...")

    time.sleep(3)

    

    # Test de tous les moteurs

    print("\n" + "=" * 60)

    print("   TEST EN COURS")

    print("=" * 60)

    

    succes = 0

    echecs = 0

    

    for moteur in range(1, 9):

        print(f"\n[{moteur}/8]", end=" ")

        

        if tester_moteur(master, target_system, moteur, THROTTLE_POURCENTAGE, DUREE_TEST):

            succes += 1

        else:

            echecs += 1

        

        # Pause avant le moteur suivant (sauf pour le dernier)

        if moteur < 8:

            time.sleep(DUREE_TEST + PAUSE_ENTRE_MOTEURS)

        else:

            time.sleep(DUREE_TEST)  # Pas de pause après le dernier

    

    # Résumé

    print("\n" + "=" * 60)

    print("   RÉSUMÉ")

    print("=" * 60)

    print(f"Tests réussis: {succes}/8")

    print(f"Tests échoués: {echecs}/8")

    print("=" * 60)

    

    # Fermeture

    print("\nFermeture de la connexion...")

    master.close()

    print("✓ Terminé")




if __name__ == "__main__":

    try:

        main()

    except KeyboardInterrupt:

        print("\n\n⚠️  Interruption par l'utilisateur (Ctrl+C)")

        sys.exit(0)

Take a look at MethodicConfigurator/ardupilot_methodic_configurator/backend_flightcontroller_commands.py at master · ArduPilot/MethodicConfigurator · GitHub

That is a class that uses pymavlink to test vehicle motors.

And here is a screenshot of the hole thing in action, testing up-to 32 motors:

Don’t trust your AI, and double check with existing codebase : for pymavlink we got a lot of example on the autotest suite :

or on mavproxy !