Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion MAVSDK_SERVER_VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v3.8.0
v3.9.0
4 changes: 4 additions & 0 deletions examples/calibration.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env python3

import asyncio
import logging
from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():

Expand Down
4 changes: 4 additions & 0 deletions examples/camera.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#!/usr/bin/env python3

import asyncio
import logging

from mavsdk.camera import (CameraError, Mode)
from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
drone = System()
Expand Down
4 changes: 4 additions & 0 deletions examples/firmware_version.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env python3

import asyncio
import logging
from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
drone = System()
Expand Down
4 changes: 4 additions & 0 deletions examples/gimbal.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#!/usr/bin/env python3

import asyncio
import logging
from mavsdk import System
from mavsdk.gimbal import GimbalMode, ControlMode, SendMode

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def get_gimbals(drone, timeout=10):
gimbals_found = [] # List to store all gimbals found
Expand Down
4 changes: 4 additions & 0 deletions examples/goto.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#!/usr/bin/env python3

import asyncio
import logging
from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
drone = System()
Expand Down
4 changes: 4 additions & 0 deletions examples/mission.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
#!/usr/bin/env python3

import asyncio
import logging

from mavsdk import System
from mavsdk.mission import (MissionItem, MissionPlan)

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
drone = System()
Expand Down
4 changes: 4 additions & 0 deletions examples/offboard_position_ned.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@
"""

import asyncio
import logging

from mavsdk import System
from mavsdk.offboard import (OffboardError, PositionNedYaw)

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
""" Does Offboard control using position NED coordinates. """
Expand Down
5 changes: 5 additions & 0 deletions examples/takeoff_and_land.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#!/usr/bin/env python3

import asyncio
import logging

from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():

Expand Down
5 changes: 5 additions & 0 deletions examples/telemetry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
#!/usr/bin/env python3

import asyncio
import logging

from mavsdk import System

# Enable INFO level logging by default so that INFO messages are shown
logging.basicConfig(level=logging.INFO)


async def run():
# Init the drone
Expand Down
52 changes: 47 additions & 5 deletions mavsdk/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,55 @@ The examples assume that the embedded ``mavsdk_server`` binary can be run. In so
Debug connection issues
-----------------------

.. note::
By default mavsdk-python will not print any output from mavsdk-server. If you are experiencing connection issues, it can pay to enable forwarding of the mavsdk-server output into the python console. You can do so with this piece of code at the top of your file:
MAVSDK-Python automatically captures and displays important messages from ``mavsdk_server``. Error and warning messages are shown by default, while informational messages can be enabled for more detailed debugging.

.. code:: python
**For basic debugging (recommended):**

import logging
logging.basicConfig(level=logging.DEBUG)
.. code:: python

import logging
logging.basicConfig(level=logging.INFO)

This will show connection attempts, version information, and any errors or warnings from ``mavsdk_server``.

**For detailed debugging:**

.. code:: python

import logging
logging.basicConfig(level=logging.DEBUG)

This shows all messages including internal debug information.

**For server-only messages:**

You can also control just the ``mavsdk_server`` output:

.. code:: python

import logging
logging.basicConfig(level=logging.WARNING) # Hide most messages
logging.getLogger('mavsdk_server').setLevel(logging.INFO) # Show server info

**To disable server messages completely:**

.. code:: python

import logging
logging.getLogger('mavsdk_server').setLevel(logging.CRITICAL) # Hide all server output

**Common error messages:**

If you see error messages like these, they indicate connection string issues:

.. code:: bash

ERROR:mavsdk_server:Unknown protocol (cli_arg.cpp:62)
ERROR:mavsdk_server:Connection failed: Invalid connection URL

Check that your connection string follows the correct format (e.g. ``udpin://0.0.0.0:14540``).

**Running mavsdk_server separately:**

In order to get more debugging information, it is possible to run the mavsdk_server binary separately.

Expand Down
65 changes: 58 additions & 7 deletions mavsdk/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,64 @@


class _LoggingThread(threading.Thread):
def __init__(self, pipe, log_fn):
def __init__(self, pipe, logger):
super().__init__()
self.pipe = pipe
self.log_fn = log_fn
self.logger = logger

def run(self):
for line in self.pipe:
self.log_fn(line.decode("utf-8").replace("\n", ""))
try:
for line in self.pipe:
if not line: # EOF reached
break

try:
message = line.decode("utf-8").replace("\n", "")

# Skip empty lines
if not message.strip():
continue

# Strip ANSI color codes used by MAVSDK
# MAVSDK uses: \x1b[31m, \x1b[32m, \x1b[33m, \x1b[34m, \x1b[37m, \x1b[0m
# Also handle \033[ variant (equivalent to \x1b[)
for escape_seq in ['\x1b[', '\033[']:
while escape_seq in message:
start = message.find(escape_seq)
if start == -1:
break
end = message.find('m', start)
if end == -1:
break
message = message[:start] + message[end + 1:]

# Parse mavsdk_server log level prefixes and map to Python logging levels
# Format is: [timestamp|Level] message (filename:line)
if "|Error] " in message:
idx = message.find("|Error] ") + 8
self.logger.error(message[idx:].strip())
elif "|Warn ] " in message:
idx = message.find("|Warn ] ") + 8
self.logger.warning(message[idx:].strip())
elif "|Info ] " in message:
idx = message.find("|Info ] ") + 8
self.logger.info(message[idx:].strip())
elif "|Debug] " in message:
idx = message.find("|Debug] ") + 8
self.logger.debug(message[idx:].strip())
else:
# Default to debug for unprefixed messages
self.logger.debug(message)
except UnicodeDecodeError:
# Skip lines that can't be decoded
continue
except (BrokenPipeError, OSError):
# Subprocess has terminated, exit gracefully
pass
finally:
# Ensure pipe is closed
if self.pipe and not self.pipe.closed:
self.pipe.close()

class System:
"""
Expand Down Expand Up @@ -120,7 +170,7 @@ async def connect(self, system_address=None):

# add a delay to be sure resources have been freed and restart mavsdk_server
await asyncio.sleep(1)


if self._mavsdk_server_address is None:
self._mavsdk_server_address = 'localhost'
Expand Down Expand Up @@ -456,13 +506,14 @@ def _start_mavsdk_server(system_address, port, sysid, compid):
"--compid", str(compid)]
if system_address:
bin_path_and_args.append(system_address)

p = subprocess.Popen(bin_path_and_args,
shell=False,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

logger = logging.getLogger(__name__)
log_thread = _LoggingThread(p.stdout, logger.debug)
logger = logging.getLogger('mavsdk_server')
log_thread = _LoggingThread(p.stdout, logger)
log_thread.start()
except FileNotFoundError:
print("""
Expand Down
2 changes: 1 addition & 1 deletion mavsdk/telemetry.py
Original file line number Diff line number Diff line change
Expand Up @@ -4739,7 +4739,7 @@ async def scaled_imu(self):

async def raw_imu(self):
"""
Subscribe to 'Raw IMU' updates.
Subscribe to 'Raw IMU' updates (note that units are are incorrect and "raw" as provided by the sensor)

Yields
-------
Expand Down
2 changes: 1 addition & 1 deletion mavsdk/telemetry_pb2_grpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ def SubscribeScaledImu(self, request, context):
raise NotImplementedError('Method not implemented!')

def SubscribeRawImu(self, request, context):
"""Subscribe to 'Raw IMU' updates.
"""Subscribe to 'Raw IMU' updates (note that units are are incorrect and "raw" as provided by the sensor)
"""
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
Expand Down
2 changes: 1 addition & 1 deletion proto
Submodule proto updated from 61b1b1 to 7bc044
Loading