Skip to content

Logging data with Matplotlib Animation issues #584

@J0hn3ch

Description

@J0hn3ch

Hi everyone, especially Bitcraze Team!

I try to use the Animation module of Matplotlib, in particular the FuncAnimation class.

I read a lot about how is implemented the Log class LogConfig class, and SyncLogger class in crazyflie-lib-python, and I try to use it to make a plotter for the stateEstimate variables that the crazyflie-firmware provide (See Crazyflie-firmware Logs API).

Until now I write this code:

if __name__ == '__main__':
    cflib.crtp.init_drivers()    # Initialize the low-level drivers

    logconf = LogConfig(name='Position', period_in_ms=100)
    logconf.add_variable('stateEstimate.y', 'float')


    # Matplotlib initial configuration
    plt.ion()  # Turn on interactive mode

    fig, ax = plt.subplots()
    ax.grid()
    ax.set_xlim(0, 100)
    ax.set_ylim(-0.5, 0.5)
    line, = ax.plot(np.array([]), np.array([]), linewidth=1.5, marker='')

    # Crazyflie instance
    with SyncCrazyflie(uri, cf=Crazyflie(rw_cache='./cache')) as scf:

      scf.cf.log.add_config(logconf) # Log configuration to logging framework

      # IMPORTANT
      with SyncLogger(scf, logconf) as logger:
         ani = animation.FuncAnimation(fig, 
                  func=partial(update_signal, signal=line), 
                  frames=logger, 
                  event_source=logconf.data_received_cb, 
                  blit=True, 
                  save_count=100
          )
      
          plt.show(block=False)

The FuncAnimation use a func parameter for the function that is repeated when an event_source callback is called (in our case, the cflib.utils.callbacks.Caller assigned to LogConfig.data_received_cb) and should get some data from the parameter frames.

The updated_signal function specified in func should use the frame to update a line plot figure, at this point, every 100ms as specified in the parameter period_in_ms in the LogConfig definition.

Errors

Caller class - Caller object has no attribute 'stop' / 'start'

Traceback (most recent call last):
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/cbook.py", line 361, in process
    func(*args, **kwargs)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 933, in _start
    self.event_source.start()
    ^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Caller' object has no attribute 'start'

AttributeError: 'Caller' object has no attribute 'start'
Traceback (most recent call last):
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/cbook.py", line 361, in process
    func(*args, **kwargs)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1244, in _on_resize
    self.event_source.stop()
    ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Caller' object has no attribute 'stop'

Error - cflib.crazyflie: Exception Callback on port [5] / RuntimeError: main thread is not in main loop

ERROR:cflib.crazyflie:Exception while doing callback on port [5]

Traceback (most recent call last):
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/cflib/crazyflie/__init__.py", line 465, in run
    cb.callback(pk)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/cflib/crazyflie/log.py", line 632, in _new_packet_cb
    block.unpack_log_data(logdata, timestamp)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/cflib/crazyflie/log.py", line 348, in unpack_log_data
    self.data_received_cb.call(timestamp, ret_data, self)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/cflib/utils/callbacks.py", line 54, in call
    cb(*args)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1450, in _step
    still_going = super()._step(*args)
                  ^^^^^^^^^^^^^^^^^^^^
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1138, in _step
    self._draw_next_frame(framedata, self._blit)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1158, in _draw_next_frame
    self._post_draw(framedata, blit)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1181, in _post_draw
    self._blit_draw(self._drawn_artists)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/animation.py", line 1206, in _blit_draw
    ax.figure.canvas.blit(ax.bbox)
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/backends/backend_tkagg.py", line 14, in blit
    _backend_tk.blit(self._tkphoto, self.renderer.buffer_rgba(),
  File "/home/ubuntu/Bitcraze_io/cfswarm_unime/.cfswarm_venv/lib/python3.12/site-packages/matplotlib/backends/_backend_tk.py", line 144, in blit
    photoimage.tk.call(_blit_tcl_name, argsid)
RuntimeError: main thread is not in main loop

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions