ros-industrial / ros2_canopen

CANopen driver framework for ROS2
https://ros-industrial.github.io/ros2_canopen/manual/rolling/
143 stars 63 forks source link

Retrieving visible string data #226

Open MartinCornelis2 opened 10 months ago

MartinCornelis2 commented 10 months ago

Ubuntu 22.04 ROS Humble

I'm trying to retrieve some data from my device of the type 0x0009 (VISIBLE STRING) for both my driver and my faker. In both cases I struggle to get this information out. As an example:

[100B]
ParameterName=Model ID
ObjectType=0x7
DataType=0x0009
AccessType=const
DefaultValue=PKP2600SI
PDOMapping=0

DRIVER: In my driver I've tried universal_get_value<> from the lely_bridge with different template arguments, however it seems that only uint types are supported and I'm not able to directly use char * or std::string. When I use uint64_tI am able to retrieve data and convert it to hex and then to ASCII to get PKP2600, however the SI is part is missing, because in candump can0 I can see that it arrives as a separate 2nd message.

As a follow up I thought to try and get the value from the object dictionary directly, however it is a protected member of the lely_driver_bridge, so as a hack I moved it to public and tried to call lower level library functions with no success. As a workaround I could use ->getProductName() which happens to be the same as the Model ID, but instead takes it from:

[DeviceInfo]
VendorName=...
VendorNumber=...
ProductName=PKP2600SI
RevisionNumber=...

but this does not solve the fact that I can't seem to get VISIBLE STRING info from my device.

FAKER For my faker I derived a new class from public canopen::BasicSlavewhere I am able to send and receive some data, however here I would also like to know the model name of the device I'm mocking. However, <type> model_name = (*this)[0x100B][0]; does not work for the types I've tried (char *, std::string, uintxxx). Either I get an error that the type does not match: Get:15:100B:00: Data type does not match, length of service parameter does not match (06070010)

Or the checker in the template says that certain functions such as TpdoGet() do not work for the type i've selected: no matching function for call to ‘lely::canopen::BasicSlave::TpdoGet<std::__cxx11::basic_string<char, std::char_traits<char>

when I check device.cpp it seems like VISIBLE_STRING is not supported, however I do find references to VISIBLE_STRING and 0x0009 in several places in the lely core libraries.

TL;DR Is there a different function that I should be calling that I missed, or is it impossible to get data of the type 0x0009 if it exceeds the uint64_t size?

hellantos commented 10 months ago

If you do this with SDO, everything with more than 32 bits of size requires multiple objects to be transmitted. This is a topic for lely canopen stack: https://gitlab.com/lely_industries/lely-core.