Velocity Feedforward Issue using Arduino library with CAN

I am working on putting together a testbed to exercise an actuator we are developing. My goal is to send open loop command profiles with position, velocity_FF, and torque_FF for performance tuning and validation. I’m using an ODrive Pro updated to 0.6.9-1 firmware.

I have a Teensy 4.1 running a timed loop and stepping through the profile at 100 Hz. I’m using the ODriveArduino Library (0.10.0). Using only the position command, I get the expected performance from a few test profiles I’ve run. I tried adding velocity feedforward, and I’m seeing some unexpected behavior.

Here’s a plot of the test profile I was running. You can see it starts out good but then the velocity feedforward drives it off the correct trajectory.

I puzzled over this for some time, then tried a test where I set the postion gain to 0 and commanded only the velocity feedforward in a simple ramped profile. This shows the problem…

I think this means the command coming from the Teensy is not being encoded correctly which seems would be related to the ODriveArduino library, or the ODrive is not interpreting it correctly.

I think I’ll set up to grab a raw CAN log to see what’s going across as the command to see if that looks as expected or not.

Wizards of ODrive, any ideas? Am I silly to be using the Arduino library for this?

CAN log: Nothing obviously wrong. I didn’t decode these but from the plot it looks like there’s a wraparound happening.

The Arduino library function accepts a floating point value.

The CAN documentation specifies the velocity and torque FF’s as 16 bit integers…

And that should be the problem, 16 bit integers are -32,768 to 32,767. So that bounds the FF range to +/- 32.7 rev/s. My application requires 100’s of rev/s.

Is there a way to scale the range accepted for the feedforwards? Or perhaps is there a way to scale the position/velocity to be calibrated to a different unit like meters?

A scale is a good idea, we can look into that! Though my immediate recommendation would be to just set the pos as well as vel/torque feedforwards directly using arbitrary parameter access. It’ll take three separate messages, but if this is the only ODrive on the bus and you’re running at 1Mbps then that’s only ~14us between each message, much smaller than the ODrive’s ~8kHz control loop update period.

Agree, but you forgot to add the 125usec it takes to transmit the message :wink:

Maybe we should change the FFWD scale on vel to 0.01, that would allow 327.67 rev/sec, seems pretty reasonable.

Agreed that .01 rev/s resolution would be a better default. That would make this a non issue for most reasonably applications, and .001 rev/s is too fine to ever really help. This might still be limiting with motors at or under 8 poles if the drives will be capable of 2000 Hz electrical frequency. I may be an edge case but was hopeful to go faster. A better behavior for the Arduino/ROS CAN library would be to saturate the max command limit rather than wraparound of the limit of feed forward term is exceeded.