Viper Quadcopter

Nope, the problem is that primitive representations do not allow you to reference constants. You should just use literal 2 instead of HEALTH_CAUTION. It is, indeed, inconvenient, but I am not sure how to approach it best and this issue is so far down the list that it’s not even tracked on the bug tracker.

--transport EXPRESSION, --tr EXPRESSION
...
Observe that the node-ID for the local node is to be configured here as well,
because per the UAVCAN architecture, this is a transport-layer property.
If desired, a usable node-ID value can be automatically found using the
command "pick-node-id"; read its help for usage information (it's useful for
various automation scripts and similar tasks).
...

Don’t get me wrong – I don’t mind answering your questions; in fact, they offer extremely valuable insights about the user’s perception of what we’re building, but I am concerned that you might be spending more of your time on this than you really have to.

You set the node-ID yourself in the string CAN(can.media.socketcan.SocketCANMedia("vcan0",8),59). See 59 at the end of it? You can see the full parameter specs in the docs or you can just execute pyuavcan show-transport to read the same docs in the command line locally.

You appear to be unaware of the fact that every invocation of CLI that instantiates a non-anonymous node will be publishing the heartbeat automatically. Just letting you know because I predict that next you will be asking why is your heartbeat published twice :wink: If you want to override the fields of that auto heartbeat you can use --heartbeat-fields.

If you have any ideas about how to make the life of the user easier (aside from improving error messages), please share. The CLI toolset does seem a bit convoluted and it could be possible to make it more approachable without requiring the user to dig through the docs for hours. Maybe.

Actually I was not going to ask that question because I read in fact the whole UAVCAN v1 crash course entry where this aspect is mentioned :wink: But yes, I fully admit guilty to the trial-and-error approach when it comes to reading documentation :blush:

Actually I’ve got a couple of suggestions to make the CLI tool easier to use.

  1. As a user using the pyuavcan publish feature I’m interested first and foremost in publishing UAVCAN data on various transport layers. That’s why my focus is on setting up the message and not configuring the transportlayer which additionally is appended at the end of a already very long bash entry (alternatively it’s in front but the manipulation of the message is at the end, also undesirable). This is actually the reason why I was unable to make the connection of the 59 node id with the 59 at the end of the --tr string - it was simply lost to my eye focus because of the awful long bash line.
  2. As a typical user I’m not going to change my transport layer 3 times a day. Probably I’ll change it never. Therefore it might be worth considering to introduce “state” to the pyuavcan CLI tool which allows to permanently configure the desired transport layer. (pyuavcan config --gobal transport=CAN). It’s probably only you as the UAVCAN devs that need to change between various transport layers on a regular basis.
  3. The transport layer configuration is done via a string. I daresay that’s unusal for the typical bash user. They(we) are used to having identifiers before the parameter which give some hint as what it is that we are configuring. E.g.
--tr=[CAN|Serial|...]
--tr=CAN [can0|vcan0|can1|...] -can-mtu-=[8|64] -can-id=(0-127)

Thank you. I think 1 and 2 are sensible points and I just registered this issue here: https://github.com/UAVCAN/pyuavcan/issues/117

Not sure about the specialized options though. I implemented this approach early in the development process but it is quite messy because you have to keep these options aware and in sync with the transport implementations, it’s just too much work to maintain reliably. I think if we made the environment variables as described in the linked issue it would solve the problem ultimately because I suppose you would just stash the config away in your ~/.bashrc and never look at it again.

Sorry for the longer break but I was caught up in quite a lot of things. There’s one thing that has been on my mind lately - Is there a RPM message in the new UAVCAN V1? I’ve been wondering since I’m putting quite some effort in a UAVCAN V1 Arduino Library which I mainly intend to use to drive 4 Zubax Orel 20 ESCs (which aren’t even ported to UAVCAN V1 yet). If there’s no RPM message I imagine the porting to be a bit more ressource consuming and I’m starting to wonder whether or not to drop the whole UAVCAN V1 thing and go back to the legacy protocol.

We are working with Dronecode to develop the Drone Profile for UAVCAN which will include the ESC status data.

I don’t think staying with v0 is sensible at all because it is inferior to v1 in many aspects.

Thank you very much for getting back to me on that one. Do you have an estimation when said Drone Profile will be available? I’m also reluctant to throw away all the work done for supporting the V1 version but it has started to look like an uphill battle.

Here you’ve mentioned that you might get to upgrade the Orel 20 to V1 in June, given that June has passed I’m wondering at what time-horizon we are looking at?

I will prioritize ESC messages but I can’t give you a timeline at the moment, not yet. It depends on the coordination of many involved parties here.

We don’t know yet. Are you available to help us here?

Once the drone profile is available and if’s similar enough with the messages used in V0 then it should be relatively easy to port the Orel 20 to UAVCAN V1, I can do that.

1 Like

Finally the Viper Quadcopter effort got a logo …

Viper Logo

… what do you think about it? :wink:

That’s not a bad logo (even the fact that the direction of the propellers is incorrect cannot spoil it).

:sweat_smile: Great catch :sweat_smile: Obviously the designer hasn’t ever owned a quadcopter and I myself didn’t think of it. Since I rolled out the logo already across all repositories I won’t change that aspect, but being made aware now it will be a constant tickle in the background of my mind :stuck_out_tongue:

Today (after a 2.5 month wait time) my Zubax Orel 20 order from Titan Elite/USA finally arrived (Corona delivery times are horrible!). Got them mounted on a Armattan Frame. Not looking forward to the wiring part. Also wondering if there could be motors with more power for those tiny 3" rotors?

1 Like

Good morning :wave:
I’m in the process of adding the handling of Service exchanges to the Arduino UAVCAN library. I’m wondering about how I can stimulate pyuavcan so that I can create the response part of the message which I need for feeding into my test code (see this line)?

pyuavcan call only shows me the request, in absence of a answering node, how would I get to the correct response for feeding into my test setup?

$ pyuavcan call 27 435.uavcan.node.ExecuteCommand.1.0 '{command: 0xCAFE, parameter: "I want a double espresso with cream"}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0",8),13)'
The request has timed out after 1.0 seconds

You can’t do that from CLI, it’s by design. Write a script instead or use Python prompt as shown here: Proposed change to variable-length arrays. When dealing with service types, add .Request or .Response after the type name.

So I’ve written myself a little script to create a ExecuteCommand.1.0 Response …

#!/usr/bin/python3.8

import pyuavcan
import uavcan
import uavcan.node

serialized = pyuavcan.dsdl.serialize(uavcan.node.ExecuteCommand_1_0.Response(status=1))
print (bytes(next(serialized)))

… which produces …

$ ./create-response.py 
b'\x01\x00\x00\x00\x00\x00\x00'

… which I interpret as a 7-byte long payload with the 1st byte containing the status and the rest being … UAVCAN “overhead”? Is this a suitable response to the request? Also I’d need to generate the right node ID for the response, the remote node id of that particular request is 27.

The definition of the response is as follows, if we remove everything but the fields:

uint8 status
void48

So the size is 7 bytes, which agrees with your observations.

This is a suitable serialized response data structure. This is a presentation-layer entity.

Now you’re talking about the transport layer. To get at this level, you need to make a service server and send a request to it. An example is shown in the PyUAVCAN Basic Demo.

Still fighting with tooling here :cry:

$ git clone https://github.com/UAVCAN/pyuavcan && cd pyuavcan
$ python3.8 -m pip install .
$ git clone https://github.com/UAVCAN/public_regulated_data_types
$ export PYTHONPATH=$(pwd)
$ pyuavcan -v dsdl-gen-pkg public_regulated_data_types/uavcan

$ ls uavcan/
diagnostic  __init__.py  metatransport  pnp        __pycache__  si
file        internet     node           primitive  register     time

And now trying to publish some heartbeat with a command that worked in the past …

$ pyuavcan publish 32085.uavcan.node.Heartbeat.1.0 '{uptime: 9876, health: 0, mode: 3, vendor_specific_status_code: 5}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0",8),13)'
Error: RuntimeError: Subsystem factory 'NodeFactory' for command 'publish' has failed: No module named 'cobs'

Any insight appreciated :pray:

This is an odd way of installing the library. Why not just pip install pyuavcan? Not saying it’s related though.

You tripped over https://github.com/UAVCAN/pyuavcan/issues/114 again. The tentative solution is to install all dependencies:

pip install pyuavcan[transport_can_pythoncan,transport_serial,cli]

I am almost there to start fixing these. Maybe tomorrow.

Good morning :coffee: :wave:

This

python 3.8 -m pip install pyuavcan[transport_can_pythoncan,transport_serial,cli]

did not solve my issue, however doing

python 3.8 -m pip install cobs

did.

As for the clumsy python 3.8 -m pip install whatever … as per earlier internet research this is the best way to avoid version/dependency f**kup which I somehow always manage to end up with. But I can’t claim any expertise insight here, all I can say is that since doing it that way I’ve had no dependency issues anymore.

Unfortunately I’m running straight into the next blocker, still the same command that worked nicely a couple of months ago:

pyuavcan publish 32085.uavcan.node.Heartbeat.1.0 '{uptime: 9876, health: 0, mode: 3, vendor_specific_status_code: 5}' --tr='CAN(can.media.socketcan.SocketCANMedia("vcan0",8),13)'
Error: TypeError: 'int' object is not iterable 

Um, that doesn’t sound plausible.

The next blocker is also a known issue: https://github.com/UAVCAN/pyuavcan/issues/116; it is now fixed in https://github.com/UAVCAN/pyuavcan/pull/132 (commit 03b95afe4da9a934a7fff23df208f9c4ecee0d4c).