Homepage GitHub

Control and debug Kotleta20 ESC with yakut

Hi
I am new to UAVCAN. I have a kotleta20 ESC from Holybro and would like to control it over UAVCAN from a raspberry pi like computer with a CAN interface. I have pyuavcan and yakut installed and the demo on pyuavcan seemed to work fine. I have connected the ESC to the can port and using candump -decaxta any I can see messages that are being read from the ESC (e.g:

(1617203624.146226) can0 RX - - 1E49AD00 [8] 01 30 FF D5 05 53 50 C9 ‘.0…SP.’
)

I do not understand how to interpret these messages and wanted to ask whether there is a good tutorial in order to learn how to publish messages into the can0 interface that can be interpreted by the ESC? I have tried to use yakut monitor but this command always fails.

Looking forward to learn about UAVCAN, it looks like a very promising protocol!

Unfortunately, Sapog (the firmware that is leveraged by Kotleta) does not yet support UAVCAN v1, but it can be easily upgraded. Would you like to help us out on this?

How does it fail?

Oh I understand, that’s why this won’t work. I see that the Sapog repository has been very inactive recently. Are there plans to keep Sapog updated or will it become legacy firmware?

How much effort is it to upgrade Sapog in order to make it compatible with UAVCAN v1?

Are there other firmwares that can be used with Kotleta20 that work with UAVCAN v1?

This is the command + error message in my terminal:

(uavcan) root@qrb5165-rb5:~/other/uavcan# yakut monitor
Traceback (most recent call last):
  File "/root/other/uavcan/uavcan/bin/yakut", line 8, in <module>
    sys.exit(main())
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/decorators.py", line 73, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/yakut/main.py", line 209, in proxy
    return loop.run_until_complete(f(*args, **kwargs))
  File "/usr/lib/python3.8/asyncio/base_events.py", line 608, in run_until_complete
    return future.result()
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/yakut/cmd/monitor/_cmd.py", line 131, in monitor
    with purser.get_node("monitor", allow_anonymous=allow_anonymous) as node:
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/yakut/main.py", line 86, in get_node
    tr = self.get_transport()
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/yakut/main.py", line 79, in get_transport
    self._transport = self._f_transport()
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/yakut/param/transport.py", line 49, in factory
    result = make_transport(purser.get_registry())
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/_transport_factory.py", line 215, in make_transport
    transports = list(itertools.chain(*(f(registers, node_id) for f in _SPECIALIZATIONS)))
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/_transport_factory.py", line 274, in _make_can
    br_arb, br_data = init("bitrate", Natural32([1_000_000, 4_000_000])).ints
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/_transport_factory.py", line 270, in init
    return registers.setdefault("uavcan.can." + name, ValueProxy(default))
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/register/_registry.py", line 260, in setdefault
    reg.assign_environment_variable(env_val)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/register/_value.py", line 159, in assign_environment_variable
    self.assign(numbers)
  File "/root/other/uavcan/uavcan/lib/python3.8/site-packages/pyuavcan/application/register/_value.py", line 132, in assign
    raise ValueConversionError(f"Source {source!r} cannot be assigned to {self!r}")
pyuavcan.application.register._value.ValueConversionError: Source [1000000] cannot be assigned to ValueProxyWithFlags(uavcan.register.Value.1.0(natural32=uavcan.primitive.array.Natural32.1.0(value=[1000000,4000000])), mutable=True, persistent=False)

Yes, there are plans to migrate it to UAVCAN v1.0 but the human resources for that are not yet allocated. If you are willing to give it a try I am ready to provide the necessary guidance. The task is relatively straightforward: remove the old libuavcan v0, introduce libcanard v1.0 instead, update the business logic in firmware/src/uavcan_node accordingly. Afterward, update the reference manual.

I am not aware of any.

Source [1000000] cannot be assigned to ValueProxyWithFlags(uavcan.register.Value.1.0(natural32=uavcan.primitive.array.Natural32.1.0(value=[1000000,4000000])), mutable=True, persistent=False)

It says that you can’t assign [1000000] to a register that contains [1000000,4000000]. The second value is required.