struct.error: unpack requires a buffer of 1 bytes

Discussions about all things Bitcraze
Post Reply
Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Thu Oct 17, 2019 7:17 pm

Hi,

I encountered some issues when I try to read the log variables. I write some codes to read the log variable and do some math. It work well at the beginning and read the desired log variables without any problem. But then, after updating a few hundred times, the code crashed and shows the following error message: (the Crazyflie firmware did not crash)
-----------------------------------------------------------------------------------------------------------------------------------------------
Exception while doing callback on port [5]

Traceback (most recent call last):
File "C:\Users\samsung pc\Desktop\crazyflie-lib-python-master\cflib\crazyflie\__init__.py", line 396, in run
cb.callback(pk)
File "C:\Users\samsung pc\Desktop\crazyflie-lib-python-master\cflib\crazyflie\log.py", line 580, in _new_packet_cb
block.unpack_log_data(logdata, timestamp)
File "C:\Users\samsung pc\Desktop\crazyflie-lib-python-master\cflib\crazyflie\log.py", line 307, in unpack_log_data
unpackstring, log_data[data_index:data_index + size])[0]
struct.error: unpack requires a buffer of 1 bytes
--------------------------------------------------------------------------------------------------------------------------------------------

Any advice would help.
Thanks in advance.

Duncan



arnaud
Bitcraze
Posts: 2204
Joined: Tue Feb 06, 2007 12:36 pm

Re: struct.error: unpack requires a buffer of 1 bytes

Post by arnaud » Mon Oct 21, 2019 11:06 am

I do not recognize this error. Is it happening during connection after a while or at connection all the time?

The best is if you could make a minimal script that shows the problem, this way we could try to reproduce it on our side.

Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

Re: struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Thu Oct 24, 2019 3:26 am

Hi, arnaud

Those log readings are from the extra sensor through the Crazyflie so might be you could regenerate this error by reading other log parameters.
The code below is the only log reading-related part in the client code. The firmware side to register log variables is similar to the "oa" deck driver.

Code: Select all

def receive_rssi(scf, lm_marker):
    print('Waiting for reading rssi value...')

    t_log_config = LogConfig(name='Target', period_in_ms=500)  # the log group name is target
    t_log_config.add_variable('target.rssi1', 'int8_t')
    t_log_config.add_variable('target.rssi2', 'int8_t')
    t_log_config.add_variable('target.rssi3', 'int8_t')
    t_log_config.add_variable('target.rssi4', 'int8_t')
    t_log_config.add_variable('target.rssi5', 'int8_t')

    a_log_config = LogConfig(name='Anchor', period_in_ms=500)  # the log group name is anchor
    a_log_config.add_variable('anchor.rssi6', 'int8_t')
    a_log_config.add_variable('anchor.rssi7', 'int8_t')

    rssi1 = -128
    rssi2 = -128
    rssi3 = -128
    rssi4 = -128
    rssi5 = -128
    rssi6 = -128
    rssi7 = -128

    with SyncLogger(scf, t_log_config) as logger:
        for log_entry in logger:
            data = log_entry[1]
            rssi1 = data['target.rssi1'] 
            rssi2 = data['target.rssi2']
            rssi3 = data['target.rssi3']
            rssi4 = data['target.rssi4']
            rssi5 = data['target.rssi5']

            # check whether rssi value is updated
            if rssi1 !=-128 or rssi2 !=-128 or rssi3!=-128 or rssi4!=-128 or rssi5!=-128:
               break

    with SyncLogger(scf, a_log_config) as logger:
        for log_entry in logger:
            data = log_entry[1]
            rssi6 = data['anchor.rssi6'] 
            rssi7 = data['anchor.rssi7']

            # check whether rssi value is updated
            if rssi6 !=-128 or rssi7 !=-128:
               break



The error happens during connection after a while. At first, the reading and data transmitting have no problem at all but after like reading 200 times, the client shows that error.

Thank you very much,
Duncan

arnaud
Bitcraze
Posts: 2204
Joined: Tue Feb 06, 2007 12:36 pm

Re: struct.error: unpack requires a buffer of 1 bytes

Post by arnaud » Thu Oct 24, 2019 10:10 am

The script you sent is not a workable script, it would be much more useful if you could send a minimal working example so that I can experiment with exactly the same code from here. The script should contain the minimum amount of code to work our of the box and show the problem.

I anyway tried to run the sync log demo (https://github.com/bitcraze/crazyflie-l ... logSync.py) modified to run for 10 minutes and I did not get any error. So basic use of sync log API with the latest version of the lib and the firmware seems to work.

Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

Re: struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Thu Oct 24, 2019 4:30 pm

Cool. So I will try to the latest version and see whether the error happens again.

Thanks.
Duncan

Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

Re: struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Wed Oct 30, 2019 1:31 am

Hi Arnaud,

I think I find another key to this error after I modified the sync log demo code to the way I use the log in my code.
Here is the code:

Code: Select all

import logging
import time

import cflib.crtp
from cflib.crazyflie import Crazyflie
from cflib.crazyflie.log import LogConfig
from cflib.crazyflie.syncCrazyflie import SyncCrazyflie
from cflib.crazyflie.syncLogger import SyncLogger

# Only output errors from the logging framework
logging.basicConfig(level=logging.ERROR)
# URI to the Crazyflie to connect to
uri = 'radio://0/80/2M'


def log_read(scf):
    lg_stab = LogConfig(name='Stabilizer', period_in_ms=100)
    lg_stab.add_variable('stabilizer.roll', 'float')
    lg_stab.add_variable('stabilizer.pitch', 'float')
    endTime = time.time() + 0.1
    with SyncLogger(scf, lg_stab) as logger:
        for log_entry in logger:
            timestamp = log_entry[0]
            data = log_entry[1]
            logconf_name = log_entry[2]
            if time.time() > endTime:
                print('[%d][%s]: %s' % (timestamp, logconf_name, data))
                break


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...')
    print('Crazyflies found:')
    count = 0
    with SyncCrazyflie(uri, cf=Crazyflie(rw_cache='./cache')) as scf:
        while 1:
            log_read(scf)
            count += 1
            print(count)
            time.sleep(0.2)



So every time I run this code, it works at the beginning but the log reading would strictly stop and the program gets stuck at the 256th reading.

Thanks.
Duncan
Attachments
1.png

arnaud
Bitcraze
Posts: 2204
Joined: Tue Feb 06, 2007 12:36 pm

Re: struct.error: unpack requires a buffer of 1 bytes

Post by arnaud » Thu Oct 31, 2019 10:02 am

Hi,
Thanks for the working example! I can reproduce the problem on my side.

Your code is continiously creating and deleting log blocks and it seems that doing that more than 256 times does not work. Each log block is assigned a 1 byte ID by the Crazyflie and what is seems is that the ID are not re-used when a block has been removed. There is a bug somewhere, either in the lib or in the Crazyflie. I am looking at where the problem might be and will create a ticket in the correct project.

Do you really need to stop and start logging? A more common way would be to use the async log API and to setup log callbacks for all your crazyflies. That way you do not have to start and top log and this problem will not appear.

Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

Re: struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Sun Nov 03, 2019 7:07 pm

Thank you very much. If always keep the logging then it would require something like the threading, right? Since the data collection would only happen in some situations, I still hope the logging could start and stop. Could you share with me some materials and resources about the async log API? I don't find them in the examples.

Duncan

arnaud
Bitcraze
Posts: 2204
Joined: Tue Feb 06, 2007 12:36 pm

Re: struct.error: unpack requires a buffer of 1 bytes

Post by arnaud » Mon Nov 04, 2019 11:57 am

The basiclog example is using the async API: https://github.com/bitcraze/crazyflie-l ... asiclog.py.

One thing to do is indeed to keep the script alive. In this simple example this is done with a loop waiting for the Crazyflie to disconnect: https://github.com/bitcraze/crazyflie-l ... #L142-L143.

Duncan
Beginner
Posts: 17
Joined: Mon Aug 27, 2018 1:13 am

Re: struct.error: unpack requires a buffer of 1 bytes

Post by Duncan » Tue Nov 05, 2019 9:50 pm

Thank you so much.

Post Reply