yakut
yakut copied to clipboard
Capture/tracing
EDIT 2021: see https://forum.uavcan.org/t/uavcan-v1-wireshark-plugin/1058/2?u=pavel.kirienko
We need the ability to log network frames into dump files and read them back for later analysis. This feature is vital for various R&D and flight recording purposes.
The feature has been discussed first in this thread: https://forum.uavcan.org/t/gui-tool-next-generation/229/2?u=pavel.kirienko. At the application level, its purpose is close to that of ROS bags: http://wiki.ros.org/Bags.
First, it was proposed to define a dedicated format, where log files are flat binaries (no global structure) consisting of an ordered set of frames: https://docs.google.com/spreadsheets/d/1yP9zXChKTaIm92Bd60jgrOSwGIeXp-CO5tGyYcaBopg/edit. As explained on the forum in the linked above thread, lack of global structure (e.g., no file header) is desirable because it allows trivial manipulations over log files (which can be huge) to be performed by naive concatenation/truncation/splitting.
Later it was observed that the log file frame format and a then-hypothetical serial link frame format would be largely identical because flat log files and serial links are structurally similar: https://forum.uavcan.org/t/yukon-design-megathread/390/115?u=pavel.kirienko. So we can use the existing (albeit still extremely experimental) serial transport for log file storage. At the architectural level, the only missing piece is the set of DSDL definitions describing transport frame data formats for various transports. Once such definitions are available, the task of log recording can be defined as listening to the network traffic in promiscuous mode, encoding each received frame into a DSDL object, and then serializing that as a message transfer over serial transport. The resulting byte sequence is then appended to the log file. Likewise, it is possible to log arbitrary metadata by using appropriate DSDL message types.
Shall this approach prove successful, we could expand this to become a de-facto standard for data logging not only by software tools but also by hardware data recorders.
This is an oft requested feature in many frameworks and is very useful for post-processing and analysis.
The primary issue with reconstruction in the past in PyUAVCAN was that the uavcan.protocol.Frame was all you got from adding a raw message handler. The converting from uavcan.protocol.Frame to uavcan.protocol.Transfer was difficult to generate (had to have a node and a bus in some circumstances). Assembling frames back into Transfers, then into known message formats was something that was only available in the listener side of a Node (which the post-processor didn't need to setup along with a Bus).
UAVCAN GUI Tool had a semi-robust method of reassembly outside of PyUAVCAN which did a similar thing, but at least required a fake bus (to let it know it was FD/nonFD I guess).
Having a mechanism in PyUAVCAN to simply take a List[Frames]
and assemble them into a List[Transfers]
then a decoded list of actual message types (catching those who don't decode correctly) would be invaluable.
Additionally, It would also be useful to create test fixtures which can feed synthetic data into a Node as well from a captured log.
Yeah, I should think about transfer reassembly in post-processing.
Observe though that this ticket is related to v1 only. PyUAVCAN v1 has nothing in common with v0.
So, should we define a UAVCAN storage format as part of the specification?
Should we extend pyuavcan to read and write this storage format?
should we define a UAVCAN storage format as part of the specification?
I am not certain yet. UAVCAN is about real-time communication, not about data storage; the latter belongs to a different domain and does not affect many of the things that UAVCAN is concerned about, such as wire compatibility and functional correctness. At any rate, I am pretty sure it's safe to just avoid answering this question for a while until we have gathered substantial empirical data on this feature.
Should we extend pyuavcan to read and write this storage format?
That is sort of my plan, hence the ticket. I could really use help here, though. Again, I am talking about PyUAVCAN v1 (branch uavcan-v1.0
).
Should we work out some tenants for a v1 based format and then the consequences for v1 recording / playback experiences?
Should we work out some tenants for a v1 based format and then the consequences for v1 recording / playback experiences?
Sure.
Per my vision, we're looking at storing raw serialized transfers of the serial transport in binary files. I have drafted out a new standard data type uavcan.metatransport.can.Frame
which models a generic CAN frame; likewise, there should be similar definitions for other transports (e.g., a UDP frame). The same definitions can be used for interface bridging; for example, a USB-CAN adapter could use the CDC-ACM class on the host side and implement tunneling by encoding CAN frames as serial transport messages of type uavcan.metatransport.can.Frame
.
Besides encoded transport frames, log files could contain arbitrary metadata such as parameters of the recorded traffic (CAN bitrate, error counters, etc. using either specific data types or a self-describing schemaless key/value format, like the register API), the time system used for timestamping (uavcan.time.TimeSystem
), and possibly free-form implementation-defined text data contained inside messages of type uavcan.diagnostic.Record
.
Does that make sense in general? Should we continue in this direction or am I missing something?
Edit: I think I just made a mistake by replying here; it would be better to move this discussion over to the forum https://forum.uavcan.org/c/dev
This is mostly implemented in a separate ad-hoc script: https://forum.opencyphal.org/t/postmortem-dump-analyzer-tool/2184
Now we need to simply clean it up a little and move into a new Yakut command (named trace
per the original proposal). Instead of capturing network events using Yakut we should instead make trace
support various existing network capture formats: candump, tcpdump, etc.