# Sending sequence of frames via CAN

**URL:** <https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915>\
**Category:** Applications & Usage\
**Created:** [August 13, 2020, 2:05pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915 "2020-08-13T14:05:32Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 2:05pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/1 "2020-08-13T14:05:32Z")

</div>

I need to send a radar frame which basically is a pointcloud and the amount of data is greater than 8 or 64 bytes, usually around 500 bytes. So at the moment, I am using SocketAPI from Linux and I am using magic word to obtain the end of the frame (so I keep reading the CAN bus until I get the Magic word of 8 bytes and therefore I know that the sequence has finished).

I was wondering, how can I implement this in UAVCAN? Should I use PyUAVCAN or Libcanard? I am not using embedded system on receiving side, rather a full ARM64 Linux system.

Also is it possible to throw away the magic word implementation and rather dump 500 bytes to UAVCAN and expect the receiver using UAVCAN to figure our where is the end of this 500 bytes?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 2:09pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/2 "2020-08-13T14:09:10Z")

</div>

> [@anur](#):
>
> Also is it possible to throw away the magic word implementation and rather dump 500 bytes to UAVCAN and expect the receiver using UAVCAN to figure our where is the end of this 500 bytes?

This is the only way to do it. Please read the [Guide](https://uavcan.org/guide/).

> [@anur](#):
>
> I was wondering, how can I implement this in UAVCAN? Should I use PyUAVCAN or Libcanard? I am not using embedded system on receiving side, rather a full ARM64 Linux system.

PyUAVCAN is probably easier to use because it offers a higher-level API.

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 2:11pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/3 "2020-08-13T14:11:47Z")

</div>

Ok I am just scared that Python will throw some exceptions but from your own experience, would you say that it will be safe to use PyUAVCAN?

Yes, I am reading the guide and I have a question regarding that. Am I correct saying that if I expect no more than 500 bytes, I just need to create a message with data[\<500] and create a subscriber that uses this message?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 2:14pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/4 "2020-08-13T14:14:49Z")

</div>

> [@anur](#):
>
> Ok I am just scared that Python will throw some exceptions but from your own experience, would you say that it will be safe to use PyUAVCAN?

Python is ill-suited for embedded systems, but you said that the receiving end is not an embedded system, so it might be adequate. If not, use Libcanard.

> [@anur](#):
>
> Am I correct saying that if I expect no more than 500 bytes, I just need to create a message with data[\<500] and create a subscriber that uses this message?

Not quite. You seem to be reasoning at the level of bytes. You need to discard this mindset and start thinking in terms of data types. What do these bytes represent? What exactly does the radar give you, at the application level?

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 2:18pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/5 "2020-08-13T14:18:13Z")

</div>

Yes, the receving machine is Linux. The sending machine is embedded. I assume this is totally okay to use PyUAVCAN on Linux and Libcanard on Embedded?

I am actually happy to disregard the bytes as I am not an embedded engineer. Ok, in that case it really is like ROS and I think I will not have problems with that. Radar is sending a header and a data, that’s it. I guess I can create a message with some header fields like timestamp and just data field which is an array.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 2:21pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/6 "2020-08-13T14:21:42Z")

</div>

> [@anur](#):
>
> Yes, the receving machine is Linux. The sending machine is embedded. I assume this is totally okay to use PyUAVCAN on Linux and Libcanard on Embedded?

Of course; otherwise, what would be the point of everything.

> [@anur](#):
>
> I am actually happy to disregard the bytes as I am not an embedded engineer. Ok, in that case it really is like ROS and I think I will not have problems with that. Radar is sending a header and a data, that’s it. I guess I can create a message with some header fields like timestamp and just data field which is an array.

Yes, it is just like ROS. I recommend keeping in mind that what you are dealing with ultimately is not some bytes but quantities modeling the real world. For example, if the radar yields an array of distance measurements in polar coordinates, then model it like `float32[100] distance`, etc. instead of `uint8[500] radar_output`.

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 3:24pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/8 "2020-08-13T15:24:04Z")

</div>

You have here a nice API for the libcanard:  
[https://github.com/UAVCAN/platform\_specific\_components](https://github.com/UAVCAN/platform_specific_components)

Can I use it together with DSDL to start my project quicker? As I am on Linux machine, I am not required to manually allocate heap and etc.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 3:29pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/9 "2020-08-13T15:29:02Z")

</div>

Yes, but! The DSDL generator is currently in a sort of half-finished state:

> <https://github.com/OpenCyphal/nunavut/pull/115>
>
> \# Notes about code:
> \- Generated code requires libcanard, as its base serializat…ion functions are utilized.
> \- Code is implemented as discussed in #112 
> \- Implemented inline functions return bit length. This is so they can nest easily in the case of not being byte-aligned.
> 
> \# Notes about PR:
> 
> As of creating this, I believe I am mostly done serialization support. There are a few fixes and cleanups to do, but the bulk of it is there. (probably some edge cases I missed too).
> 
> Deserialization support is next, and I will likely finish that tomorrow.
> 
> I will take this PR out of Draft mode once it is in a state I believe should start getting in depth reviews (I will also clean up the commits a bit so you aren't looking through 20 random commits).

You can either serialize your types manually (it’s very easy to do using the helper functions from `canard_dsdl.h`), or you can help us finalize that PR to merge it quicker (it’s 99% done).

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 8:23pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/10 "2020-08-13T20:23:15Z")

</div>

Ok but first I am just trying to grasp this new way of communication for me 🙂  
So I know getting more and more familiar. I have a specific code question if you do not mind.

Suppose I have created my uavcan message called Distance and after serialization I have ID for example 56.  
Now, when I want to subscribe to the topic with such message, I have to pass a CanardTransfer when accepting a message from the topic. As far as I understood, when I finally receive a message, this transfer will hold my message and the payload. So in my case, will this be sufficient to first declare a member of struct like this:

```auto
const CanardTransfer distance_transfer = {
    .timestamp_usec = transmission_deadline, // Zero if transmission deadline is not limited.
    .priority = CanardPriorityNominal,
    .transfer_kind = CanardTransferKindMessage,
    .port_id = 1234, // This is the subject-ID.
    .remote_node_id = CANARD_NODE_ID_UNSET, // Messages cannot be unicast, so use UNSET.
    .transfer_id = my_message_transfer_id,
    .payload_size = 100, // My maximum number of distance points
    .payload = **Not sure what to declare here;**
};

```

And after receiving a payload I just need to deserialize it.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 8:37pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/11 "2020-08-13T20:37:28Z")

</div>

Sorry, I don’t understand your question.

> [@anur](#):
>
> after serialization I have ID for example 56

What does this mean?

> [@anur](#):
>
> Now, when I want to subscribe to the topic with such message, I have to pass a CanardTransfer when accepting a message from the topic.

No. To subscribe, you call [`canardRxSubscribe(...)`](https://github.com/UAVCAN/libcanard/blob/03b017ace46ee0a926837fa916559bc02160a673/libcanard/canard.h#L582-L587). You don’t need a transfer for that.

> [@anur](#):
>
> when I finally receive a message, this transfer will hold my message and the payload.

Yes. The library will create an instance of `CanardTransfer` for you, whose payload you then deserialize and process. You do not need to instantiate `CanardTransfer` unless you want to publish a message.

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 13, 2020, 8:54pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/12 "2020-08-13T20:54:44Z")

</div>

Ah okay now it makes sense! I was just a bit lost with the guide + github + C++ API, sorry.

Regarding the ID, when we create a subscriber, we have to pass `const CanardPortID port_id` which I believe is Subject ID of the message. So what I mean is that if I want to create a custom message, I need to give my message an ID correct? Like Heartbeat has its own ID 32085. So In order to give an ID, I have to serialize my message first.

Btw, if I want to use this message for example: [https://github.com/UAVCAN/public\_regulated\_data\_types/blob/master/uavcan/primitive/array/Integer32.1.0.uavcan](https://github.com/UAVCAN/public_regulated_data_types/blob/master/uavcan/primitive/array/Integer32.1.0.uavcan)  
Do I need to deserialize them to obtain the Subject ID?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 13, 2020, 9:08pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/13 "2020-08-13T21:08:16Z")

</div>

Serialization and subject-ID assignment are independent processes. You assign your subject identifiers at the system definition time, like you do with topics in ROS. Say, you might proclaim that “let there be radar readings published at subject-ID 56”, and there will be radar readings at subject-ID 56. No messages needed, see? You just decide it and it’s done.

Now, when actually publishing a new radar message, you serialize it, and when invoking [`canardTxPush(...)`](https://github.com/UAVCAN/libcanard/blob/03b017ace46ee0a926837fa916559bc02160a673/libcanard/canard.h#L411) you pass your serialized data along with your **56** into it (packed into an instance of CanardTransfer).

When subscribing, you already know that you should be on a lookout for messages published with the subject-ID of 56.

Subject-ID == topic name.

---

<div class="post-metadata">

**Author:** ![anur](https://forum.opencyphal.org/letter_avatar_proxy/v4/letter/a/8e8cbc/32.png) [@anur](https://forum.opencyphal.org/u/anur)\
**Post date:** [August 14, 2020, 10:01am UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/14 "2020-08-14T10:01:22Z")

</div>

Yes makes sense.

When I want to accept a frame using canardRxAccept function, how can I know which message I received? For example I already have 3 subscriptions for 3 radar devices that share the same message:

```auto
(void) canardRxSubscribe(&ins_, CanardTransferKindMessage, 201, 100, CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC, &radar1_subscription_);
(void) canardRxSubscribe(&ins_, CanardTransferKindMessage, 202, 100, CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC, &radar2_subscription_);
(void) canardRxSubscribe(&ins_, CanardTransferKindMessage, 203, 100, CANARD_DEFAULT_TRANSFER_ID_TIMEOUT_USEC, &radar3_subscription_);

```

But when I try to accept it, can it be any of the 3 messages? As I understood there could be only 1 CanardInstance

I mean I can just take the ID of the transfer (I mean my ID which I am sending from the Radar so I can differentiate) and compare but is there a “correct” way?

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 14, 2020, 3:55pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/15 "2020-08-14T15:55:51Z")

</div>

> [@anur](#):
>
> how can I know which message I received?

You just look at the field [`port_id`](https://github.com/UAVCAN/libcanard/blob/03b017ace46ee0a926837fa916559bc02160a673/libcanard/canard.h#L223-L224) of the received CanardTransfer.

---

<div class="post-metadata">

**Author:** ![nacansino](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/nacansino/32/535_2.png) [@nacansino](https://forum.opencyphal.org/u/nacansino)\
**Post date:** [August 15, 2020, 2:15am UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/16 "2020-08-15T02:15:59Z")

</div>

Replying because I also want to know if there is a “recommended” way of consuming the canard RX frames other than switch.

Right now, the only information in the Canard transfer frame that identifies its structure is `port_id`. So if I have a consumer task, say `processReceivedTransfer(const CanardTransfer* const rxf)`, the task would have a dirty `switch( rxf->port_id ){}` which will call the respective deserializer functions (which I’m also patiently waiting for…).

Which made me think that it must mean that all DSDL datatypes that will be used at an application-level must be labeled with port\_ids. Hmm, interesting.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 15, 2020, 3:34am UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/17 "2020-08-15T03:34:12Z")

</div>

> [@nacansino](#):
>
> Replying because I also want to know if there is a “recommended” way of consuming the canard RX frames other than switch.

Your preferred methods of data handling are entirely out of the scope of the library (and Specification). If you’re dealing with a large number of ports, declarative approaches based on a handler registry might be preferred, where you define a dictionary mapping port-ID to handler functions, and traverse it whenever you receive a new transfer. Up to you.

> [@nacansino](#):
>
> Which made me think that it must mean that all DSDL datatypes that will be used at an application-level must be labeled with port\_ids.

No.

A port-ID identifies a specific service within the system, like, say, airspeed measurement, or a radar sensor, or a motor drive. The service requires a data type definition to facilitate data transactions. A data type may be used with different service instances (e.g., multiple cameras) or even completely different services (e.g., the same type can be used to report an estimation and to command a setpoint). Excepting few edge cases, most of which are already addressed by the standard data type set (`uavcan.*`), data types defined by vendors/developers will not need a fixed port-ID at all. Instead, the mapping between subjects/services and their identifiers will be established according to the design of the system at a later stage. As I wrote earlier, it helps to reason about subject-IDs as topics, they are basically identical in their purpose.

There is a short explanation in [Choosing Message and Service IDs](https://forum.opencyphal.org/t/choosing-message-and-service-ids/889). If you are building a UAVCAN-powered system, you really need to read [the Guide](https://uavcan.org/guide/), where this question is explored in-depth.

---

<div class="post-metadata">

**Author:** ![nacansino](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/nacansino/32/535_2.png) [@nacansino](https://forum.opencyphal.org/u/nacansino)\
**Post date:** [August 15, 2020, 2:14pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/18 "2020-08-15T14:14:35Z")

</div>

> [@pavel.kirienko](#):
>
> Your preferred methods of data handling are entirely out of the scope of the library (and Specification). If you’re dealing with a large number of ports, declarative approaches based on a handler registry might be preferred, where you define a dictionary mapping port-ID to handler functions, and traverse it whenever you receive a new transfer. Up to you.

Got it. Is my understanding correct that the handling of Canard frames after it was released from the RX buffer (given that memory is freed afterwards) is up to the user of the library?

> [@pavel.kirienko](#):
>
> A port-ID identifies a specific service within the system, like, say, airspeed measurement, or a radar sensor, or a motor drive. The service requires a data type definition to facilitate data transactions. A data type may be used with different service instances (e.g., multiple cameras) or even completely different services (e.g., the same type can be used to report an estimation and to command a setpoint). Excepting few edge cases, most of which are already addressed by the standard data type set (`uavcan.*`), data types defined by vendors/developers will not need a fixed port-ID at all. Instead, the mapping between subjects/services and their identifiers will be established according to the design of the system at a later stage. As I wrote earlier, it helps to reason about subject-IDs as topics, they are basically identical in their purpose.

Thank you for the explanation. I was actually on the brink of making the mistake of tying the semantics to the data-types.

The allocation of port IDs and deciding on which datatypes to use confused me because I was acting both as a vendor and the integrator; basically I’m designing the whole system with no external components.

---

<div class="post-metadata">

**Author:** ![pavel.kirienko](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/pavel.kirienko/32/9_2.png) [@pavel.kirienko](https://forum.opencyphal.org/u/pavel.kirienko)\
**Post date:** [August 16, 2020, 9:15pm UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/19 "2020-08-16T21:15:14Z")

</div>

> [@nacansino](#):
>
> Is my understanding correct that the handling of Canard frames after it was released from the RX buffer (given that memory is freed afterwards) is up to the user of the library?

I think you mean not frames but transfers, `CanardTransfer` (a frame is a transport-layer entity, a transfer is something you deal with at the presentation layer). If so, yes, your understanding is correct.

---

<div class="post-metadata">

**Author:** ![nacansino](https://forum.opencyphal.org/user_avatar/forum.opencyphal.org/nacansino/32/535_2.png) [@nacansino](https://forum.opencyphal.org/u/nacansino)\
**Post date:** [August 17, 2020, 1:27am UTC](https://forum.opencyphal.org/t/sending-sequence-of-frames-via-can/915/20 "2020-08-17T01:27:35Z")

</div>

Yes, I mean CanardTransfer, not transport frames. Thanks for clarifying!
