How to fill and read a nunavut::support::VariableLengthArray<std::uint8_t, 50>

Hi there!

I’m currently attempting to use the .dsdl data types for the first time. I’m wondering if you could give me an example on how to fill and then read a nunavut::support::VariableLengthArray<std::uint8_t, 50>

More specifically. I am trying to fill the GetInfo name property. I had a look at the examples on 107-arduino-cyphal, and they show how to fill the parameter property of ExecuteCommand::Request_1_1. They show it like this:

 /* Request some coffee. */
  std::string const cmd_param("I want a double espresso with cream!");
  ExecuteCommand::Request_1_1 req;
  req.command = 0xCAFE;
  std::copy_n(cmd_param.begin(),
              std::min(cmd_param.length(), req.parameter.capacity()),
              req.parameter.begin());

I have assumed that this is the same process for the GetInfo name property as in the dsdl files they have the same definition of uint8[]

This is what I’ve tried so far, but yakut doesn’t read anything as the name of my node.

  uavcan::node::GetInfo::Response_1_0 response;
  Serial.println("Get info requested");

  response.protocol_version.major = CANARD_CYPHAL_SPECIFICATION_VERSION_MAJOR;
  response.protocol_version.minor = CANARD_CYPHAL_SPECIFICATION_VERSION_MINOR;

  response.hardware_version.major = HW_VERSION_MAJOR;
  response.hardware_version.minor = HW_VERSION_MINOR;
  response.software_version.major = SW_VERSION_MAJOR;
  response.software_version.minor = SW_VERSION_MINOR;
  response.software_vcs_revision_id = VCS_REVISION_ID;

  response.unique_id = get_unique_id();
  std::string const name("rossrobotics.mk4.cantranslator.robot");
  std::copy_n(
    name.begin(),
    std::min(name.length(), response.name.capacity()),
    response.name.begin());

Nowhere does it say how to convert this back into a string when its been received by a node to be able to use/print to screen. How would I do that?

Thanks in advance
Rebecca

The first snippet looks correct to me and requires no changes, as far as I see.

The problem with Yakut has nothing to do with DSDL. It is simply unable to fetch the uavcan.node.GetInfo response for some unrelated reason. Maybe this service is not implemented by the node. To check, invoke the service manually and evaluate the response (-v is added for verbosity, add another one for extra verbosity which may aid in diagnosing the problem):

y -v q 42 uavcan.node.GetInfo

Make a null-terminated char buffer and copy the bytes there. Note that soon we’re going to add proper string support to DSDL and Nunavut, see here for details: Add support for strings and byte arrays by pavel-kirienko · Pull Request #97 · OpenCyphal/pydsdl · GitHub.

Thank Pavel for your quick response. I did y -v q 35 uavcan.node.GetInfo and this was its response

2023-05-24 12:23:05 0000039 INF yakut.cmd.call: Request object: uavcan.node.GetInfo.Request.1.0()
2023-05-24 12:23:05 0000039 INF yakut.param.transport: Transport constructed from registers: CANTransport(SocketCANMedia('can0', mtu=8), local_node_id=42)
2023-05-24 12:23:05 0000039 INF pycyphal.transport.can.media.socketcan._socketcan: SocketCANMedia('can0', mtu=8) FIXME: acceptance filter configuration is not yet implemented; please submit patches! Requested configuration: ext:xxx1x0xxxxxxxxx0101010xxxxxxx, ext:xxxxx0xxxxxxxxxxxxxxxx0101010, ext:xxx0x0xx11101010101010xxxxxxx
2023-05-24 12:23:05 0000039 INF yakut.cmd.call: Request duration [second]: transport layer: 0.000000, application layer: 0.008191, application layer overhead: 0.008191
430:
  protocol_version: {major: 1, minor: 0}
  hardware_version: {major: 0, minor: 1}
  software_version: {major: 0, minor: 1}
  software_vcs_revision_id: 0
  unique_id: [0, 0, 0, 0, 0, 0, 0, 0, 228, 97, 144, 55, 3, 18, 33, 35]
  name: ''
  software_image_crc: []
  certificate_of_authenticity: ''

I must that something wrong in my code so i’ll look into it.

Thanks I’ll implement copying the bytes there and check their example one works too.
Oh that’s good to know about the string support thanks!

Wait, I see an issue now in your first snippet. Either it’s incomplete or you’re missing the resize operation. Either do it manually or (much preferable) use std::back_inserter.

A PR with a fix would be welcome.

Btw. The node info service is implemented for 107-Arduino-Cyphal, the library is fully standard compliant.

You can see how to correctly fill the VLA here.

Thanks so much is exactly what i was looking for! All working now :slight_smile:

1 Like

If you could send a pull request to the repository fixing this deficiency, that would be nice.

To fix the example code?
Sure i can do that

2 Likes

PR has been made this morning :slight_smile:

1 Like

And merged! Thank you very much :bow: