OpenCyphal / yakut

Simple CLI tool for diagnostics and debugging of Cyphal networks
https://opencyphal.org
MIT License
49 stars 10 forks source link

"yakut monitor" is throwing errors with SocketCAN #21

Closed JacobCrabill closed 3 years ago

JacobCrabill commented 3 years ago

Any ideas? I just upgraded pyuavcan, yakut, nunavut, and a number of other dependent packages tonight.

Using a PCAN-USB CAN adapter (shows up as a socketcan interface; works fine with can-utils and yakut {pub|sub}).

Python 3.9.1 Yakut 0.5.2 pyuavcan 1.2.4

NodID Mode Health VSSC Uptime         VProtcl VHardwr VSoftware(major.minor.vcs.crc)            Unique-ID                        Name                    
    1 oper nomina    0     0d00:00:49 ?       ?       ?                                         ?                                ?                       
    3 ?    ?      ?    offline          1.0     0.0     0.5                                     8d5361a31e63e8b36942aea7855b9d8d org.uavcan.yakut.monitor
   20 oper nomina    0     0d00:01:16 ?       ?       ?                                         ?                                ?                       
APPLICATION LAYER CONNECTIVITY MATRIX [t/s=transfer/second] Colors: pub/cln│sub/srv│(pub+sub)/(cln+srv)│activity│uavcan.node.port.List is published/not│
MESSG    1   20 ∑t/s ∑B/s     
   22   4         4  242    22
   30   2         2   36    30
   31   2         2   33    31
 7509  30    1   31  220  7509
∑t/s   38    1   39      ↖ t/s
∑B/s  525    6       532      
RQ+RS    1   20 ∑t/s ∑B/s     
∑t/s    0    0    0      ↖ t/s
∑B/s    0    0         0      
TOTAL    1   20 ∑t/s ∑B/s     
∑t/s   38    1   39           
∑B/s  525    6       532      
Total transport layer errors:        0         Values averaged over 10.0 sec
2021-04-21 20:15:55 0023949 ERR pyuavcan.application.heartbeat_publisher: HeartbeatPublisher(heartbeat=uavcan.node.Heartbeat.1.0(uptime=8, health=uavcan.node.Health.1.0(value=0), mode=uavcan.node.Mode.1.0(value=0), vendor_specific_status_code=49), priority=NOMINAL, period=1.0) publisher task exception: [Errno 22] Invalid argument
Traceback (most recent call last):
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/application/heartbeat_publisher.py", line 203, in _task_function
    if not await pub.publish(self.make_message()):
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/presentation/_port/_publisher.py", line 113, in publish
    return await self._maybe_impl.publish(message, self._priority, self._loop.time() + self._send_timeout)
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/presentation/_port/_publisher.py", line 190, in publish
    return await self.transport_session.send(transfer, monotonic_deadline)
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/transport/can/_session/_output.py", line 206, in send
    return await self._do_send(can_id, transfer, monotonic_deadline)
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/transport/can/_session/_output.py", line 163, in _do_send
    if await self._send_handler(transaction):
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/transport/can/_can.py", line 327, in _do_send
    num_sent = await self._maybe_media.send(
  File "/home/jacob/Workspace/uavcan-v1/venv/lib/python3.9/site-packages/pyuavcan/transport/can/media/socketcan/_socketcan.py", line 128, in send
    await asyncio.wait_for(
  File "/home/jacob/local/lib/python3.9/asyncio/tasks.py", line 478, in wait_for
    return fut.result()
  File "/home/jacob/local/lib/python3.9/asyncio/selector_events.py", line 446, in sock_sendall
    n = sock.send(data)
OSError: [Errno 22] Invalid argument
^C
Aborted!
(venv) jacob@jacob-desktop:~/Workspace/uavcan-v1$ python --version
Python 3.9.1
(venv) jacob@jacob-desktop:~/Workspace/uavcan-v1$ yakut --version
yakut, version 0.5.2
(venv) jacob@jacob-desktop:~/Workspace/uavcan-v1$ pip freeze | grep pyuavcan
pyuavcan==1.2.4
pavel-kirienko commented 3 years ago

Is CAN FD enabled on the SocketCAN interface? It can be done by setting the MTU = 72 (64 bytes of payload + 8 bytes of the kernel overhead).

If you don't want CAN FD, use register uavcan.can.mtu (the corresponding environment variable is UAVCAN__CAN__MTU).

JacobCrabill commented 3 years ago

I'm not trying to use CAN-FD though, so I have that disabled on the socket... I take it by this you're saying that yakut expects CAN-FD is eanbled by default?

pavel-kirienko commented 3 years ago

Yes. This is documented in the PyUAVCAN API documentation linked from the Yakut manual. I expect that most systems that adopt UAVCAN/CAN v1 will be FD-capable, so it makes sense to default to that.

On Thu, Apr 22, 2021, 06:30 Jacob Crabill @.***> wrote:

I'm not trying to use CAN-FD though, so I have that disabled on the socket... I take it by this you're saying that yakut expects CAN-FD is eanbled by default?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/UAVCAN/yakut/issues/21#issuecomment-824511668, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZFIZFIHEBK7UML6BTI6IDTJ6J7FANCNFSM43LSBHZQ .

pavel-kirienko commented 3 years ago

@JacobCrabill should I close this issue?

JacobCrabill commented 3 years ago

I believe that worked - it runs without errors, but gives me no data now - I'm going to assume for now that's an issue with my setup and worry about it later.

For other's reference:

sudo ip link set can0 up type can bitrate 1000000 dbitrate 1000000 fd on
export YAKUT_TRANSPORT="CAN(can.media.socketcan.SocketCANMedia('can0',16),3)"
export UAVCAN__CAN__BITRATE=1000000
export UAVCAN__CAN__MTU=16

For the purposes of testing a non-FD network (and assuming I were to use a non-FD-compatible adapter such as a Babel), how would I get this to work in that case?

JacobCrabill commented 3 years ago

Actually, I'm not quite following how to configure this - I've been using yakut successfully to pub/sub messages with FD disabled; it's purely the monitor function that is requiring CAN-FD - but then enabling CAN-FD breaks the normal pub/sub of messages.

pavel-kirienko commented 3 years ago

Wait, this isn't right. The docs say (in a slightly roundabout way but nevertheless) that if you use a transport initialization expression, the environment variables are ignored. Also, my fault here is that above I spoke about the Linux kernel MTU setting, not Yakut/PyUAVCAN:

It can be done by setting the MTU = 72 (64 bytes of payload + 8 bytes of the kernel overhead).

When configuring Yakut, you just set the MTU as-is without any overheads included. So, in your case, the configuration to disable FD is:

export UAVCAN__CAN__IFACE=socketcan:can0
export UAVCAN__CAN__BITRATE=1000000 1000000
export UAVCAN__CAN__MTU=8

If you want FD:

export UAVCAN__CAN__IFACE=socketcan:can0
JacobCrabill commented 3 years ago
export UAVCAN__CAN__IFACE=socketcan:can0
export UAVCAN__CAN__BITRATE=1000000 1000000
export UAVCAN__CAN__MTU=8

Ok, I simply had the MTU wrong - I've been a little confused as to whether the MTU refers to the overall message size (including header), or the payload alone (so 8 or 16). I think I've seen references online to both variants. In this case for non-FD, setting the Yakut / PyUAVCAN MTU to 8 solved the issue.

So the updated environment variable to make these systems all play happily together is:

export YAKUT_TRANSPORT="CAN(can.media.socketcan.SocketCANMedia('can0',8),3)"

Or to use your UAVCAN_CAN_* variables above.

pavel-kirienko commented 3 years ago

@JacobCrabill fyi #22

JacobCrabill commented 3 years ago

Cool. Thanks @pavel-kirienko!