canopen icon indicating copy to clipboard operation
canopen copied to clipboard

Trouble understanding how to utilize the TPDO and RPDO to set target position

Open NicoPowers opened this issue 2 years ago • 1 comments

Hello,

I would like to firstly thank you for creating this package, it has a lot of potential and will simplify a lot of my future robotics projects.

I recently got a motor working in terms of being able to read some parameters via SDO; for instance, the following code works fine:

motorNetwork = Network()

motorNetwork.connect(channel='can0', bustype='socketcan', bitrate=1000000)

motor_1 = motorNetwork.add_node(RemoteNode(1, "YZ_MOTOR.eds"))

motor_1.nmt.state = 'PRE-OPERATIONAL'

print(int.from_bytes(motor_1.sdo.upload(0x1018, 1), 'little'))

And it outputs the expected value for my Vendor ID.

But I am having trouble understanding how I can simply set a target position using the RPDO or TPDO services. As far I understand it, I need to use RPDO because this motor is a remote node relative to my PC acting as a CAN Master, so the remote node is receiving data from my PC so I have to use RPDO.

However even after looking at the example documentation for PDO, I still don't understand how this is working and how I can apply this to my specific motor and EDS file that I was given.

I have a couple questions regarding the example documentation for PDO:

  1. What is the add_variable doing exactly? I thought once we read the PDO using node.tpdo.read() and node.rpdo.read(), it should have everything it needs to access whatever I need to do.
  2. Where are the strings for the add_variable coming from? like 'Application Commands', 'Command All', etc.? Is there an EDS file that goes along with this example so I can see how this is related and how I can adapt this to my specific EDS file?
  3. Why is the RPDO[4] sending out the speed at an interval of 0.1 seconds? Why not just send the desired speed once? Why does it have to keep sending it? Is there a timeout associated to storing variables for velocity and position? Like if I set a target position to my motor, will it store it in volatile flash and then erase it after a short time, so I need to keep sending it?
  4. Why are there 4 slots for the TPDO and RPDO? Why not just have one slot since each one can have multiple variables? And how do you know which one to use, how come the example uses the fourth index instead of the first one?

Now for my specific application, when I do node.rpdo.read() it shows: pdo_target_position

So using that information, how can I go about writing a simple script to just send a target position value via PDO? I don't know which index to use, or how to use the add_variable functions to have it point to the right COB-ID for the target position used by the PDO service.

This is the EDS file I am using if that helps: YZ_MOTOR.eds.txt

Thank you for your help and time. I have tried learning about the PDO service through the official CANOpen documentation but it still confuses me exactly how it is working to ensure no protocol overhead (because it is still using CAN so why is there no protocol overhead?), so any insight and clarifications on TPDO and RPDO would be greatly appreciated.

Thank you!

NicoPowers avatar Apr 03 '22 18:04 NicoPowers

Hi @NicoPowers,

I will try to explain the best I can your questions. Well, first lets try to understand why because it is still using CAN so why is there no protocol overhead?, i'm assuming you are referring to SDO vs PDO. They are different mechanisms to send/read data over can to/from a node, SDO are used to access entries (i.e., objects) of the object dictionary directly, normally during configuration phase. SDO are more expensive (thus communication overhead) since it is a confirmed communication service, for each communication sent to a node it will receive an acknowledge response (e.g., similar to tcp) and you can only access on object at a time. For example for reading an object using SDO you will use 4 messages (2 each way). On The other hand, PDO are design to be used as broadcast, they will be consumed but they will not generate acknowledge response (e.g., similar to UDP). Also, they can be configured to read/write to more than one object of the Object Dictionary (e.g., see the EDS file), so for instance you can write/read using PDO's to two objects simultaneously with one message, while using SDO you will have 2 x 4 = 8 messages, you see where i'm going right, this is the so called overhead.

My advice is to first and foremost understand a bit of the protocol and it's mechanism, a quick google search will get you up to speed, without any order of importance A very good short explanation provided by csselectronics, Can-cia, wikipedia.

What is the add_variable doing exactly? I thought once we read the PDO using node.tpdo.read() and node.rpdo.read(), it should have everything it needs to access whatever I need to do.

PDO's allows you to access Objects in the Object Dictionary in one message, but they must first be configured (which objects to which PDO's), and this can be done by using the EDS file and loading it into the application, downloading the OD from the remote node into the application, or configure it during runtime using the add_variable function.

Where are the strings for the add_variable coming from? like 'Application Commands', 'Command All', etc.? Is there an EDS file that goes along with this example so I can see how this is related and how I can adapt this to my specific EDS file?

Look inside the examples folder. It is not related with the example in the documentation example, but it can help you jump start. The 'Application Commands' are friendly designations provided when configuring the PDO's for ease of access to the mapped objects. They can be defined in the EDS, or by code.

Why is the RPDO[4] sending out the speed at an interval of 0.1 seconds? Why not just send the desired speed once? Why does it have to keep sending it? Is there a timeout associated to storing variables for velocity and position? Like if I set a target position to my motor, will it store it in volatile flash and then erase it after a short time, so I need to keep sending it?

Short answer is, it's doing what it was told to do, it is a simple example of how to periodically send values to a remote node. It all depends on your use case. While the node is running, to the best of my knowledge, it will store the values you sent until it is powered down, so you can send values only when something has change.

Why are there 4 slots for the TPDO and RPDO? Why not just have one slot since each one can have multiple variables? And how do you know which one to use, how come the example uses the fourth index instead of the first one?

Again, is an example. And again, to the best of my knowledge by default it is used the first four, with some manufactures having other also pre-configured. But, you can have up to 512 PDOs configured. You know which one to used based on the configuration you provided, if you have a specific Object mapped in TPDO[2] you will use that TPDO.

af-silva avatar Apr 04 '22 11:04 af-silva