Viper Quadcopter

Good morning everyone :coffee: :wink:

I’m part of a small group which is working on

building a Arduino MKR Vidor 4000 based quadcopter flight controller with all the features found in state-of-the art quadcopter designs making resourceful use of all components (MCU, FPGA, WiFi NINA, …) located on the Vidor 4000 in order to control a Micro Aerial Vehicle (MAV) .

In our opinion the Arduino MKR Vidor 4000 is an especially interesting board for such an application since the onboard FPGA enables interesting capabilities, such as being used as an optical flow sensor in combination with a downward facing camera.

The current block diagramm looks like that:

A current 3D rendering of the quadcopter and some of its electronics can be seen here (the red boards on top are Zubax Orel 20 ESCs).


The repositories containing all relevant code are located within the 107-systems GitHub organisation. One repository that might be of special interest to this community is 107-Arduino-UAVCAN which is currently work in progress and will provide an abstraction of libcanard in the form of an Arduino library.

Some more eye candy: Here’s a picture of the Arduino MKR Vidor 4000 with a MKR CAN Shield on top and the VidorCameraAdapter attached to it’s MiniPCIe slot.

I’m looking forward to hear your thoughts on this one :wink:

Edit: Adding pictures after being granted rights to more than one picture by Pavel (thank you :wink:)

1 Like

Thanks Alexander. I’ve fixed the forum settings to avoid similar issues with posting in the future.

I’ve got a question: How can I “see/generate” the CAN frame(s) for any kind of UAVCAN message (e.g. heartbeat) using the existing tools? My basic idea is that I want to generate a couple of test frames and feed it into our Arduino UAVCAN library to see wether or not everything works as intented.

Use the PyUAVCAN CLI tool. We’ve got a couple of examples published in the crash course, too:

The tool works on any platform but the CAN transport is currently only supported on GNU/Linux because it supports only SocketCAN as the backend. If you would like to use CAN on a different platform, please help us resolve this:

Hi Pavel,

Thanks for getting back to me. I’ve studied the crash course but I didn’t make the connection that I could just wip up a virtual can (= vcan :man_facepalming:) and see the frames there. Thank you! :heart:

1 Like

Hi :wave:
After trying a l o t I’ve still not managed to get the pyuavcan tool installed AND running. Either my linux has the most f**ked up Python environment ever (totally possible since this a system used heavily for all sorts of development work) or I just don’t get it. Is there a really failsafe way to get pyuavcan and all its dependencies installed regardless how the rest of the system is set-up?

$ python3.6 -m pyuavcan
Traceback (most recent call last):
  File "/usr/lib/python3.6/", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/lib/python3.6/", line 142, in _get_module_details
    return _get_module_details(pkg_main_name, error)
  File "/usr/lib/python3.6/", line 109, in _get_module_details
  File "/usr/local/lib/python3.6/dist-packages/pyuavcan/", line 69, in <module>
    raise RuntimeError('A newer version of Python is required')
RuntimeError: A newer version of Python is required
$ python3.8 -m pyuavcan
Traceback (most recent call last):
  File "/usr/lib/python3.8/", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
ModuleNotFoundError: No module named 'ruamel'
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/", line 63, in apport_excepthook
    from apport.fileutils import likely_packaged, get_recent_crashes
  File "/usr/lib/python3/dist-packages/apt/", line 23, in <module>
    import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'

Original exception was:
Traceback (most recent call last):
  File "/usr/lib/python3.8/", line 192, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/home/alex/.local/lib/python3.8/site-packages/pyuavcan/_cli/commands/", line 16, in <module>
    import ruamel.yaml
ModuleNotFoundError: No module named 'ruamel'
python3.8 -m pip install ruamel
Collecting ruamel
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/pip/", line 215, in main
    status =, args)
  File "/usr/share/python-wheels/requests-2.18.4-py2.py3-none-any.whl/requests/", line 935, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url:

Yes. In your case that would be:

python3.8 -m pip install pyuavcan

If you also want CLI tools, use this instead:

python3.8 -m pip install pyuavcan[cli]

More info:

1 Like

It works :rocket: :heart: !

But another issue whose source I don’t quite understand …

$ pyuavcan dsdl-gen-pkg dsdl_src/my_project
Error: RuntimeError: test saturated was already defined.

Can you please re-run the command with -vv and post the output here?

Sure. Here’s the data gathered via

pyuavcan -vv dsdl-gen-pkg dsdl_src/my_project 2> pyuavcan.errlog

pyuavcan.errlog (69.7 KB)

It’s a version mismatch that was just fixed in Sorry. As we are still working on Nunavut and PyUAVCAN, occasionally things go out of sync causing problems of this kind. Can you please install the latest master of PyUAVCAN? Just clone the repo and run pip install . from its root directory. I think that should get you sorted out. I will be releasing a new version soon.

No worries :wink: Unfortunately it’s still not quite cutting it.

Doing this …

git clone
cd pyuavcan
python3.8 -m pip install .

… results in …

Processing /home/alex/projects/tools/pyuavcan
Collecting pydsdl~=1.4 (from pyuavcan==1.1.0.dev0)
  Using cached
Collecting numpy~=1.16 (from pyuavcan==1.1.0.dev0)
  Using cached
Collecting nunavut==0.2.3 (from pyuavcan==1.1.0.dev0)
  Using cached
Collecting setuptools (from nunavut==0.2.3->pyuavcan==1.1.0.dev0)
  Using cached
Installing collected packages: pydsdl, numpy, setuptools, nunavut, pyuavcan
  Running install for pyuavcan ... done
Successfully installed numpy-1.18.4 nunavut-0.2.4 pydsdl-1.4.2 pyuavcan-1.1.0.dev0 setuptools-46.4.0

When running …

pyuavcan -vv dsdl-gen-pkg dsdl_src/my_project 2> pyuavcan.errlog2

… I get another error:
pyuavcan.errlog2 (79.3 KB)

Since your commit is about pinning nunavut to 0.2.3 I’m wondering if I have a unclean build setup since it obviously uses 0.2.4 again.

Successfully installed numpy-1.18.4 nunavut-0.2.4 pydsdl-1.4.2 pyuavcan-1.1.0.dev0 setuptools-46.4.0

EDIT: For the record …

pyuavcan$ git log -n 1
commit 5463c0df6522885e87605db168a016d1a1d94541 (HEAD -> master, origin/master, origin/HEAD)
Merge: 5752640 2598d07
Author: Pavel Kirienko <>
Date:   Tue May 26 15:59:47 2020 +0300

    Merge pull request #111 from jxltom/patch-1
    Update pydsdl as requirement to 1.4

Please run pip install nunavut==0.2.3 or just remove it and reinstall pyuavcan again (Nunavut will be pulled in automatically as a dependency).


$ python3.8 -m pip install .
Collecting nunavut==0.2.3 (from pyuavcan==1.1.0.dev0)
  Using cached
Installing collected packages: pydsdl, numpy, setuptools, nunavut, pyuavcan
  Running install for pyuavcan ... done
Successfully installed numpy-1.18.4 nunavut-0.2.3 pydsdl-1.4.2 pyuavcan-1.1.0.dev0 setuptools-46.4.0

Show nunavut version just to be safe:

$ python3.8 -m pip show nunavut
Name: nunavut
Version: 0.2.3
Summary: Generate code from DSDL using Jinja2 templates.

Running pyuavcan still generates an error (same as reported here):

pyuavcan -vv dsdl-gen-pkg dsdl_src/my_project 2> pyuavcan.errlog3

pyuavcan.errlog3 (79.3 KB)

Ah. Your root namespace directory dsdl_src/my_project does not appear to contain any DSDL source files. Maybe you forgot to specify version numbers? It should be like Foo.1.0.uavcan instead of Foo.uavcan.

The error message is absolutely unclear and it’s a bug. If you could confirm the above I am going to file it as such on GitHub.

Good morning :wave:

Yes I can in fact confirm that dsdl_src/myproject is empty. Also I don’t want to use any custom UAVCAN types, I just wanted to print a heartbeat on vcan0 via

$ pyuavcan pub 32085.Heartbeat.1.0 '{uptime:0xDEADBEEF, health:HEALTH_NOMINAL, mode:MODE_OPERATIONAL}'
Error: RuntimeError: Subsystem factory 'NodeFactory' for command 'publish' has failed: No module named 'uavcan'

Alas, it didn’t work either so I thought the command listed above the publish command in the crash course is necessary.

It failed because you didn’t generate the types. For that, you just need to run this:

pyuavcan dsdl-gen-pkg

Naturally, if you don’t have any custom types then you shouldn’t ask the generator to generate code for them.

Thank you for pointing this out. Obviously that’s not obvious for a first time user and the error message wasn’t very beneficial either. Now that I’ve generated types for UAVCAN only …

user@dir$ ls uavcan/
diagnostic  file  internet  metatransport  node  pnp  primitive  register  si  time

… I’ve attemted to publish a basic message using a basic example available within the pyuavcan documentation.

user@dir$ pyuavcan publish uavcan.diagnostic.Record.1.0 '{"text": "Hello world!"}'
Error: RuntimeError: Subsystem factory 'NodeFactory' for command 'publish' has failed: No module named 'uavcan'

For sure that error means something to your, for me it’s utterly meaningless :wink:

The tool is behaving as intended. The root cause is that the directory that contains the generated package is not listed as the Python import look-up path. This is mentioned in the documentation if you look at pyuavcan dsdl-gen-pkg --help:

--output OUTPUT, -O OUTPUT
Path to the directory where the generated packages will be stored.
If not specified, defaults to the current working directory.
Existing packages will be overwritten entirely.
The destination directory should be in PYTHONPATH to use the generated

You can fix it like this, if you use bash/sh:

export PYTHONPATH=/your/directory:$PYTHONPATH

The problem with the bad error message is registered at