Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Collapse
Brand Logo

ModalAI Forum

  1. ModalAI Support Forum
  2. VOXL Compute & Autopilot
  3. VOXL 2
  4. Can't connect to drone from laptop using MAVSDK

Can't connect to drone from laptop using MAVSDK

Scheduled Pinned Locked Moved VOXL 2
mavsdkmavlink-servermavlink
2 Posts 1 Posters 1.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    luisdelavega
    wrote on last edited by luisdelavega
    #1

    I've got a Starling Max 2 (VOXL2) connected to my home network. My laptop is also connected to that same network. I'm trying to connect to the drone using MAVSDK-Python but it just doesn't work. I've lost count of everything I've tried, nothing related to MAVSDK has worked for me.

    I've updated the configuration file’s primary_static_gcs_ip field at /etc/modalai/voxl-mavlink-server.conf to my laptops IP address.

    I'm able to connect with it using pymavlink. I can adb shell in and see the messages coming in by running voxl-inspect-mavlink mavlink_from_gcs. But like I said, MAVSDK just does not connect to the VOXL2...

    Here's an actual snippet I'm trying to run:

    #!/usr/bin/env python3
    
    import asyncio
    import time
    from mavsdk import System
    from pymavlink import mavutil
    
    async def send_heartbeat_and_param_requests(target_ip="192.168.1.187", target_port=14550):
        """Send MAVLink heartbeats and parameter requests to initiate connection with VOXL2"""
        print(f"Sending heartbeats to {target_ip}:{target_port}")
        
        # Create a UDP connection to VOXL2
        connection = mavutil.mavlink_connection(f'udpout:{target_ip}:{target_port}')
        
        # Important: Set specific system and component IDs
        # System ID should not be 1 (typically the vehicle) or 255
        # Component ID should NOT be 0 as that's invalid for a source
        connection.source_system = 2       # Use 2 for a secondary GCS
        connection.source_component = 1    # Use 1 for autopilot component
        
        # Send heartbeats in a loop
        counter = 0
        while True:
            # Send a heartbeat message
            connection.mav.heartbeat_send(
                mavutil.mavlink.MAV_TYPE_GCS,              # Type: Ground Control Station
                mavutil.mavlink.MAV_AUTOPILOT_INVALID,     # Autopilot type
                0,                                          # Base mode
                0,                                          # Custom mode
                mavutil.mavlink.MAV_STATE_ACTIVE           # System status
            )
            
            counter += 1
            if counter % 5 == 0:  # Every 5 seconds
                # Send a parameter request list (this is what QGC does on connection)
                connection.mav.param_request_list_send(
                    1,     # Target system (default autopilot is usually 1)
                    190    # Target component (default autopilot component)
                )
                
                # Send a ping message
                connection.mav.ping_send(
                    int(time.time() * 1000),  # Unix timestamp in milliseconds
                    0,                         # Sequence
                    connection.source_system,  # System ID
                    connection.source_component # Component ID
                )
            
            print(f"Heartbeat sent (count: {counter})")
            await asyncio.sleep(1)  # Send heartbeats at 1Hz
    
    async def connect_to_drone():
        print("Connecting to VOXL2...")
        
        drone = System()
        
        # Different connection string formats to try
        await drone.connect(system_address="udp://:14550")
        
        print("Waiting for drone to connect...")
        timeout = 60  # Extended timeout
        start_time = asyncio.get_event_loop().time()
        
        try:
            async for state in drone.core.connection_state():
                print(f"Connection state: {state}")
                
                if state.is_connected:
                    print(f"Connected to drone!")
                    return drone
                
                # Check if we've timed out
                current_time = asyncio.get_event_loop().time()
                if current_time - start_time > timeout:
                    print(f"Connection timed out after {timeout} seconds")
                    break
                    
                await asyncio.sleep(1)
                
        except Exception as e:
            print(f"Connection error: {e}")
        
        return None
    
    async def main():
        # Start sending heartbeats in the background
        heartbeat_task = asyncio.create_task(send_heartbeat_and_param_requests())
        
        # Wait to ensure heartbeats are being received
        await asyncio.sleep(5)
        
        # Try to connect to the drone
        drone = await connect_to_drone()
        
        # If connected, do something with the drone
        if drone and drone.core:
            try:
                # Print basic information
                info = await drone.info.get_version()
                print(f"Version Info: {info}")
            except Exception as e:
                print(f"Could not get info: {e}")
        
        # Clean up the heartbeat task
        heartbeat_task.cancel()
        try:
            await heartbeat_task
        except asyncio.CancelledError:
            print("Heartbeat task cancelled")
    
    if __name__ == "__main__":
        # Run the asyncio loop
        asyncio.run(main())
    

    It never even gets to print out the "Waiting for drone to connect..." mesage. The code doesn't execute past the await drone.connect(system_address="udp://:14550") line.

    For the await drone.connect(system_address="udp://:14550") line I've tried every permutation I've found. With or without the VOXL2 IP address. I've used udpout and all other variants, none work.

    I've tried with and without sending the messages using pymavlink in case there is some conflict.

    I've tried connecting with specific sysid and compid like below:

    # Create a System object with specific system ID and component ID
    # These match the IDs we're using in the heartbeat sender
    drone = System(sysid=2, compid=1)
    

    I don't know what else to do. Any help will be greatly appreciated.

    L 1 Reply Last reply
    0
    • L luisdelavega

      I've got a Starling Max 2 (VOXL2) connected to my home network. My laptop is also connected to that same network. I'm trying to connect to the drone using MAVSDK-Python but it just doesn't work. I've lost count of everything I've tried, nothing related to MAVSDK has worked for me.

      I've updated the configuration file’s primary_static_gcs_ip field at /etc/modalai/voxl-mavlink-server.conf to my laptops IP address.

      I'm able to connect with it using pymavlink. I can adb shell in and see the messages coming in by running voxl-inspect-mavlink mavlink_from_gcs. But like I said, MAVSDK just does not connect to the VOXL2...

      Here's an actual snippet I'm trying to run:

      #!/usr/bin/env python3
      
      import asyncio
      import time
      from mavsdk import System
      from pymavlink import mavutil
      
      async def send_heartbeat_and_param_requests(target_ip="192.168.1.187", target_port=14550):
          """Send MAVLink heartbeats and parameter requests to initiate connection with VOXL2"""
          print(f"Sending heartbeats to {target_ip}:{target_port}")
          
          # Create a UDP connection to VOXL2
          connection = mavutil.mavlink_connection(f'udpout:{target_ip}:{target_port}')
          
          # Important: Set specific system and component IDs
          # System ID should not be 1 (typically the vehicle) or 255
          # Component ID should NOT be 0 as that's invalid for a source
          connection.source_system = 2       # Use 2 for a secondary GCS
          connection.source_component = 1    # Use 1 for autopilot component
          
          # Send heartbeats in a loop
          counter = 0
          while True:
              # Send a heartbeat message
              connection.mav.heartbeat_send(
                  mavutil.mavlink.MAV_TYPE_GCS,              # Type: Ground Control Station
                  mavutil.mavlink.MAV_AUTOPILOT_INVALID,     # Autopilot type
                  0,                                          # Base mode
                  0,                                          # Custom mode
                  mavutil.mavlink.MAV_STATE_ACTIVE           # System status
              )
              
              counter += 1
              if counter % 5 == 0:  # Every 5 seconds
                  # Send a parameter request list (this is what QGC does on connection)
                  connection.mav.param_request_list_send(
                      1,     # Target system (default autopilot is usually 1)
                      190    # Target component (default autopilot component)
                  )
                  
                  # Send a ping message
                  connection.mav.ping_send(
                      int(time.time() * 1000),  # Unix timestamp in milliseconds
                      0,                         # Sequence
                      connection.source_system,  # System ID
                      connection.source_component # Component ID
                  )
              
              print(f"Heartbeat sent (count: {counter})")
              await asyncio.sleep(1)  # Send heartbeats at 1Hz
      
      async def connect_to_drone():
          print("Connecting to VOXL2...")
          
          drone = System()
          
          # Different connection string formats to try
          await drone.connect(system_address="udp://:14550")
          
          print("Waiting for drone to connect...")
          timeout = 60  # Extended timeout
          start_time = asyncio.get_event_loop().time()
          
          try:
              async for state in drone.core.connection_state():
                  print(f"Connection state: {state}")
                  
                  if state.is_connected:
                      print(f"Connected to drone!")
                      return drone
                  
                  # Check if we've timed out
                  current_time = asyncio.get_event_loop().time()
                  if current_time - start_time > timeout:
                      print(f"Connection timed out after {timeout} seconds")
                      break
                      
                  await asyncio.sleep(1)
                  
          except Exception as e:
              print(f"Connection error: {e}")
          
          return None
      
      async def main():
          # Start sending heartbeats in the background
          heartbeat_task = asyncio.create_task(send_heartbeat_and_param_requests())
          
          # Wait to ensure heartbeats are being received
          await asyncio.sleep(5)
          
          # Try to connect to the drone
          drone = await connect_to_drone()
          
          # If connected, do something with the drone
          if drone and drone.core:
              try:
                  # Print basic information
                  info = await drone.info.get_version()
                  print(f"Version Info: {info}")
              except Exception as e:
                  print(f"Could not get info: {e}")
          
          # Clean up the heartbeat task
          heartbeat_task.cancel()
          try:
              await heartbeat_task
          except asyncio.CancelledError:
              print("Heartbeat task cancelled")
      
      if __name__ == "__main__":
          # Run the asyncio loop
          asyncio.run(main())
      

      It never even gets to print out the "Waiting for drone to connect..." mesage. The code doesn't execute past the await drone.connect(system_address="udp://:14550") line.

      For the await drone.connect(system_address="udp://:14550") line I've tried every permutation I've found. With or without the VOXL2 IP address. I've used udpout and all other variants, none work.

      I've tried with and without sending the messages using pymavlink in case there is some conflict.

      I've tried connecting with specific sysid and compid like below:

      # Create a System object with specific system ID and component ID
      # These match the IDs we're using in the heartbeat sender
      drone = System(sysid=2, compid=1)
      

      I don't know what else to do. Any help will be greatly appreciated.

      L Offline
      L Offline
      luisdelavega
      wrote on last edited by luisdelavega
      #2

      UPDATE

      I've simplified my snippet and I'm now able to "connect" to the VOXL2 via MAVSDK. It's still now working as I would expect it to, but first, here's my new script:

      #!/usr/bin/env python3
      
      import asyncio
      from mavsdk import System
      
      target_ip="192.168.1.187"
      target_port=14550
      
      async def connect_to_drone():
          print("Connecting to VOXL2...")
          
          # Create a System object with specific system ID and component ID
          # These match the IDs we're using in the heartbeat sender
          print("Creating System object...")
          drone = System()
          
          # Different connection string formats to try
          print("Connecting to drone...")
          await drone.connect(system_address=f"udp://{target_ip}:{target_port}")
          
          print("Waiting for drone to connect...")
          timeout = 60  # Extended timeout
          start_time = asyncio.get_event_loop().time()
          
          try:
              async for state in drone.core.connection_state():
                  print(f"Connection state: {state}")
                  
                  if state.is_connected:
                      print(f"Connected to drone!")
                      return drone
                  
                  # Check if we've timed out
                  current_time = asyncio.get_event_loop().time()
                  if current_time - start_time > timeout:
                      print(f"Connection timed out after {timeout} seconds")
                      break
                      
                  await asyncio.sleep(1)
                  
          except Exception as e:
              print(f"Connection error: {e}")
          
          return None
      
      async def main():
          # Try to connect to the drone
          drone = await connect_to_drone()
          
          # If connected, do something with the drone
          if drone and drone.core:
              try:
                  # Print basic information
                  info = await drone.info.get_version()
                  print(f"Version Info: {info}")
              except Exception as e:
                  print(f"Could not get info: {e}")
      
      if __name__ == "__main__":
          # Run the asyncio loop
          asyncio.run(main())
      

      When I run this script I see only 3 logs:

      Connecting to VOXL2...
      Creating System object...
      Connecting to drone...
      

      When I adb shell and run voxl-inspect-mavlink mavlink_from_gcs I now see that the VOXL2 is receiving a heartbeat:

      ID Mavlink MSG Name Counter Hz
      0 heartbeat 5 1.1

      But like I mentioned above, the code doesn't execute past await drone.connect(system_address=f"udp://{target_ip}:{target_port}").

      I've tried udpout and nothing changes.

      1 Reply Last reply
      0

      Hello! It looks like you're interested in this conversation, but you don't have an account yet.

      Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

      With your input, this post could be even better 💗

      Register Login
      Reply
      • Reply as topic
      Log in to reply
      • Oldest to Newest
      • Newest to Oldest
      • Most Votes


      ModalAI
      Categories Recent Tags ModalAI.com Docs
      © 2026 ModalAI® · Accelerating autonomy for smaller, smarter, safer drones · Powered by NodeBB
      • Login

      • Don't have an account? Register

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups