DEBUG_PRINT in Python

Firmware/software/electronics
Post Reply
dastonge
Beginner
Posts: 6
Joined: Tue Jul 14, 2020 9:51 pm

DEBUG_PRINT in Python

Post by dastonge »

Hi,

We have been using the 'DEBUG_PRINT' to do some high level debuging on our firmware changes lately. It works well inside the cfclient. How can we grab the 'DEBUG_PRINT' output in Python (outside of cfclient)? Is there a logparam for that? If yes, what and where is it documented?


Thank you for your support,
David.
arnaud
Bitcraze
Posts: 2390
Joined: Tue Feb 06, 2007 12:36 pm

Re: DEBUG_PRINT in Python

Post by arnaud »

You can setup a callback to get the console string while connected to a Crazyflie. This is done here in the client for example: https://github.com/bitcraze/crazyflie-c ... Tab.py#L71

In a script it would look like something like "cf.console.receivedChar.add_callback(callback_function)".
dastonge
Beginner
Posts: 6
Joined: Tue Jul 14, 2020 9:51 pm

Re: DEBUG_PRINT in Python

Post by dastonge »

Hi Arnaud,

We got there already and tried it without luck. A basic functionnal example would be great.
arnaud
Bitcraze
Posts: 2390
Joined: Tue Feb 06, 2007 12:36 pm

Re: DEBUG_PRINT in Python

Post by arnaud »

Hi,

The best is always to add what you tried and what did not work in your question, it would have saved at least a round trip here :).

I modified the ramp.py example to add console printing to it, the change is as follow:

Code: Select all

diff --git a/examples/ramp.py b/examples/ramp.py
index d5d9808..ec36f98 100644
--- a/examples/ramp.py
+++ b/examples/ramp.py
@@ -50,11 +50,15 @@ class MotorRampExample:
         self._cf.disconnected.add_callback(self._disconnected)
         self._cf.connection_failed.add_callback(self._connection_failed)
         self._cf.connection_lost.add_callback(self._connection_lost)
+        self._cf.console.receivedChar.add_callback(self._console_incoming)
 
         self._cf.open_link(link_uri)
 
         print('Connecting to %s' % link_uri)
 
+    def _console_incoming(self, console_text):
+        print(console_text, end='')
+
     def _connected(self, link_uri):
         """ This callback is called form the Crazyflie API when a Crazyflie
         has been connected and the TOCs have been downloaded."""
The key was to add the callback setup before connection, not after, otherwise I was not getting the startup console message (they where likely already transferred during the connection process).

For reference, the full example now looks like this:

Code: Select all

# -*- coding: utf-8 -*-
#
#     ||          ____  _ __
#  +------+      / __ )(_) /_______________ _____  ___
#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
#
#  Copyright (C) 2014 Bitcraze AB
#
#  Crazyflie Nano Quadcopter Client
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#  MA  02110-1301, USA.
"""
Simple example that connects to the first Crazyflie found, ramps up/down
the motors and disconnects.
"""
import logging
import time
from threading import Thread

import cflib
from cflib.crazyflie import Crazyflie

logging.basicConfig(level=logging.ERROR)


class MotorRampExample:
    """Example that connects to a Crazyflie and ramps the motors up/down and
    the disconnects"""

    def __init__(self, link_uri):
        """ Initialize and run the example with the specified link_uri """

        self._cf = Crazyflie(rw_cache='./cache')

        self._cf.connected.add_callback(self._connected)
        self._cf.disconnected.add_callback(self._disconnected)
        self._cf.connection_failed.add_callback(self._connection_failed)
        self._cf.connection_lost.add_callback(self._connection_lost)
        self._cf.console.receivedChar.add_callback(self._console_incoming)

        self._cf.open_link(link_uri)

        print('Connecting to %s' % link_uri)

    def _console_incoming(self, console_text):
        print(console_text, end='')

    def _connected(self, link_uri):
        """ This callback is called form the Crazyflie API when a Crazyflie
        has been connected and the TOCs have been downloaded."""

        # Start a separate thread to do the motor test.
        # Do not hijack the calling thread!
        Thread(target=self._ramp_motors).start()

    def _connection_failed(self, link_uri, msg):
        """Callback when connection initial connection fails (i.e no Crazyflie
        at the specified address)"""
        print('Connection to %s failed: %s' % (link_uri, msg))

    def _connection_lost(self, link_uri, msg):
        """Callback when disconnected after a connection has been made (i.e
        Crazyflie moves out of range)"""
        print('Connection to %s lost: %s' % (link_uri, msg))

    def _disconnected(self, link_uri):
        """Callback when the Crazyflie is disconnected (called in all cases)"""
        print('Disconnected from %s' % link_uri)

    def _ramp_motors(self):
        thrust_mult = 1
        thrust_step = 500
        thrust = 20000
        pitch = 0
        roll = 0
        yawrate = 0

        # Unlock startup thrust protection
        self._cf.commander.send_setpoint(0, 0, 0, 0)

        while thrust >= 20000:
            self._cf.commander.send_setpoint(roll, pitch, yawrate, thrust)
            time.sleep(0.1)
            if thrust >= 25000:
                thrust_mult = -1
            thrust += thrust_step * thrust_mult
        self._cf.commander.send_setpoint(0, 0, 0, 0)
        # Make sure that the last packet leaves before the link is closed
        # since the message queue is not flushed before closing
        time.sleep(0.1)
        self._cf.close_link()


if __name__ == '__main__':
    # Initialize the low-level drivers (don't list the debug drivers)
    cflib.crtp.init_drivers(enable_debug_driver=False)
    # Scan for Crazyflies and use the first one found
    print('Scanning interfaces for Crazyflies...')
    available = cflib.crtp.scan_interfaces()
    print('Crazyflies found:')
    for i in available:
        print(i[0])

    if len(available) > 0:
        le = MotorRampExample(available[0][0])
    else:
        print('No Crazyflies found, cannot run example')
dastonge
Beginner
Posts: 6
Joined: Tue Jul 14, 2020 9:51 pm

Re: DEBUG_PRINT in Python

Post by dastonge »

Thank you!

So it looks like our main issues were:
- not connecting the callback before creating the link
- sending too much debug data (high frequency)

Thank you for your support.
Post Reply