Cool but would it work on a Corexy?

Big thanks for your answer @PJohnson. Very clear.

At what kind of frequency is the Odrive sampling / looking at the step / dir signal if I may ask? It’ll help me determine at what kind of speeds I can still run vs the encoder settings?

Also I’m wording of you know more about the second order filter on the Odrive for step / dir?

Anyways, I now fully understand the die side of Strp dir only. I really like feed forward, so that’s a pity (I’m an NVH Engineer and making a model of my 3D printer and ultimately I would love to but the dynamic model into the controller.

But first things first. I think my steps will be to:

  1. get aquanted with the Odrive and get a setup running to test and try.
  2. use Step / Dir to see if I can hit enough precision in the motion
  3. try and print something ;-).
  4. take it from there to see how to improve as suggested by all of you. Thanks for that!

But now I’ll have to wait for all the hw first…:relieved:

If speed at all, I’d like to opt for a printer design that does really small layers (if at all) as indeed I see that extruders limit at the moment. All of this is not needed perhaps, but it sure is cool and learn all of this!

Hi PJohnson,

Do you have an estimate on how much slower Odrives control loop may react vs a stepper motor with step+direction?

I have an odrive on order now. I am initially planning to use a mix of closed loop BLDC and steppers on a 3d printer and they would need to be synchronized

As a first step over the next few weeks i hope to dig in to the Odrive and kliiper firmware source a little, to see if i can implement klippers communication protocol, command que, sync and step generation directly on the odrive.

Can you suggest what i need to read up on to better understand “Velocity and/or acceleration feedfoward” would the input still be step direction + velocity and acceleration, or i guess it could be each part of trapezoid move using External motion control ( ie Marlin / Klipper etc) allowing synchronized moves between odrive and other motor drives?

I haven’t looked at klippers motion planning source yet, but the developer doc’s make it sound like all the info required is in the move() class before the step timings are generated and sent to the MCU. Klipper Code flow of a move command

i am probably a bit out of my depth, but i will have a better look at this over the next few days and see if i have a chance of hacking something together.

Thanks

1 Like

@Quintin_Brand ODrive handles step/dir inputs via interrupts. The estimated limit is a 50kHz step rate, but I’m not aware if that has been tested. For reference, the ODrive control loop runs at 8kHz. Getting more than one interrupt per control loop cycle isn’t a problem - it’s just a larger input step. The limit here with step/dir is step size vs achievable max speed (due to the step rate limit). For the input filter, it looks like that is part of a newer firmware than master - my apologies. I’m not sure when it was added.

The 2nd order filter code is here on the devel branch. Based on the input filter gains and position/velocity error, feedforward terms are calculated for position, velocity and acceleration. It isn’t unique to the step/dir input, just a feature that could be useful.

I think you’re on the right track!

@bungle I’m not sure how much slower the ODrive control loop reacts compared to a stepper motor. Note that it isn’t unique to ODrive, it’s a characteristic of all feedback control systems. In the situation of ODrives and steppers on the same machine using step/dir commands, the “reaction speed” difference should not be enough to be noticeable. I think it would be noticeable if you were trying to fling the bed off the printer (but at that point you’re way beyond what a NEMA 17 is capable of).

In my opinion, there is not much benefit to implementing the klipper command protocol on ODrive vs using step/dir from a printer controller to ODrive. The information is the same, so the only difference is that it’s over a more reliable communication method.

I think it would be difficult to modify klipper such that it outputs step times and position/velocity commands in a synchronized way, but I could be wrong.

For the velocity/acceleration feedforward (really velocity is the most important), this is a good graphical reference.

For step generation, a trapezoidal velocity profile is made for a move command in the gcode. A position profile is calculated from the velocity profile. Then, step times are calculated to minimize the error between the “achievable stepper motion” and the desired position profile.

For the feedforward idea, in klipper, you’d take the position and velocity profiles and sample them at a fixed rate. In other words, if the move takes 1s total, slice that up into pos/vel commands for every 1ms of the move. Each position/velocity sample is then a command sent to ODrive. No need for step/dir inputs to ODrive with this scheme.

1 Like

Really really helpful again. So to try and summarize for me with the question if I got it right?:

  1. Sampling on the step / dir Odrive input is probly in range of MHz or at least high kHz range.
  2. a step / dir “pulse” triggers the interrupt (with time stamp “accuracy” of the MHz sampling). It can take up to about 50k events per second. The time stamps / trigger events / steps are converted to position. Furthermore the time difference between pulses are converted to velocity.
  3. the position and velocity is handed to the Odrive control loop which takes the last / current pulse received (e.g
    position info) in its 8kHz cycle. Therefore the control loop has no trouble when within a control cycle multiple pulses passed as it takes the latest / current position for the following cycle. This is beneficial because in this way one can’t miss out on steps in successive cycles for being bounded by 8kHz. So where at slow motor speeds it is just 1 step one can also handle multiple steps with one cycle for high rev. So no loss of steps dye to the 8kHz cycle.

Odrive for my application would be in position mode and the control using feedback makes sure the motor gets to the requested position by feedback.

In this view the 50k samples do have accurate time stamp information which is important to estimate the velocity. The 50k samples should be seen as the max steps a second the Odrive can handle steps. So 50k pulse / cps is max rev and therfor is an important trade-off between accuracy vs speed.

Looking at the control loop I have a bit more trouble to think this through, but thank you very much to point me to the actual code!

So what I like a lot here is that both position and velocity are taken into account. I’d think velocity is computed from the difference in the two last steps hence the MHz sampling.

With velocity taken into account as well I see no big impact in performance while being “only” 8kHz cycle. I guess it means that the acceleration is updated with 8kHz “sampling” where its amplitude changes in discrete steps. And here is the difference Towen pointed me at that if using the Odrive motion planning one could make nicer motion with for example a step on the jerk or even higher order derivatives?

Perhaps the second order filter I think @Wetmelon pointed at is perhaps a filter on the velocity estimate…

Hope this is all correct? I start to get a couple of ideas and hence the question up front: the 8kHz cycle is directly coupled to the amount of computations done or does it still have some headroom for additional computations in the loop?

I’m asking because I’d know how the 3D controller behaves in acceleration events etc :thinking:

That’s not quite it.

Every step pulse triggers an interrupt which increments the target position by a constant amount (configurable). No other actions are taken. The time stamp of the pulse is not recorded.

At a rate of 8kHz, the control loop reads the target position and applies control outputs to drive the motor to that position. It is during this phase that, if we know the inertia of the system, we can pre-compute the torque and speed curves we need to achieve a 2nd order (mass-spring-damper) behavior of the load. This allows us to “feed forward” those terms to the controller, instead of relying on only the error between target position and actual position. This significantly improves the control bandwidth, allowing for higher gains and faster settling time with less overshoot. This is the Input Filter that we’re referring to.

If we don’t know the inertia of the system, we could theoretically measure the # of pulses per 8kHz and estimate a desired velocity or acceleration, but this is often too noisy at slow speeds, so would need filtering anyway. The better approach is to guess / approximate the inertia and use the input filter.

Hmm, thx :wink: :wink: !

Ok I started checking the code again and wrote many things that I deleted again to now find myself reading the documentation on GitHub. I simply didn’t get that I could read a lot of the detailed functionality here ;-). OOPS.

The amount is more than enough to keep me busy for a while :wink:

I’m digging in to the code and start to see the connection between the dynamic model of my CoreXY to be and the feedback and forward implementation on the ODrive. Question before I go down the rabbit hole though:

The 8kHz control cycle: how much headroom is there left for additional computation with that cycle? Or will any operation immediately impact the cycle frequency? Here I’m focusing on the step / dir - position control.

Thx!

Not much. That being said, we’re doing a low level refactor next, which I suspect will wring out quite a bit more performance.

Hmm, ok, well I see two possible improvements for a CoreXY:

  1. When moving in X or Y different inertia are felt. On my design say X=0,5kg and Y=1kg. So the inertia feedback would benefit a split in both directions (requiring add and subtract of the two encoder signals too).
  2. I also computed the resonance frequencies of gantry - belt helt at Emotor system and could (try) build feedforward for the flexible modes too.

And the last thing I’m thinking about is how to determine 3D controller jerk allowing “instant” speed changes.

Did you get anywhere with your firmware? I am looking to build a pen plotter, so far I haven’t found a clear cut way to send gcode to an odrive.

No I did not unfortunately. Work has kept me awfully busy last year and it still does. No time fir hobby at the moment and the Odrive is still in its original box… :-(.

But step / dir is the easiest way for sure and if you use an SKR1.4 for example you can wire it directly to the board as it had pins to place a custom stepper driver.

I would recommend klipper if you are on marlin and want to switch. I am used to RRF, so I’d now would either buy a duet2 (with extension board as I have more dof to control) for it has direct connectors for step / dir or they and get RRF to run on the SKR1.4 (new possibility lately).

I think that the pulse train (step/dir) will contain more then enough frequency content to serve as a good control signal for the Odrive. The trouble will be to tune the combi of move and filament extrusion.

Hole this helps you into your journey!

Thanks for the info!

Here’s the one thing - I really want to be able to move the gantry by hand and have the firmware / software / controller or whatever know the new position.

Currently my only lead is linux cnc, even then I don’t think the Odrive board will report its position while in step/dir mode so I’d need a 2nd set of encoders maybe?

Any idea if that’s achievable?

There’s a you tube video on a odrive pen plotter.
Several actually.
Using step /direction .
Crazy fast to.
And he’s aprochable ,

Great thread.
But no one is asking about noise of the system.

Did anyone succeed at this. BTW, klipper does not only have step/dir. This is the low level commands. This is equivalent to distance, velocity and acceleration. It would be nice to close the thread with some conclusion. If this actually was already working.

queue_step oid=7 interval=7458 count=10 add=331

I’m working actively on my project again. I’m mostly stopped effort on developing my own firmware and am instead looking at creating a plugin for Grbl HAL. Grbl HAL is a port of the tried and true GRBL firmware for more modern 32-bit microcontrollers. It supports a plugin system for interfacing with specialized peripheral types. There is already a plugin for interfacing with SPI/I2C stepper drivers, so it should be very doable to add a plugin for an ODrive controlled axis. It’ll be a few weeks at minimum before I spend any time working on the software. My ODrive has been acting up ever since I did the V5 upgrade.

1 Like

Any more done on this.
It would be good to know if it’s still going

No, I’ve been sidetracked with other projects. I haven’t forgotten about it, just not expecting any movement in the near future.

Cheers.
I’m in the beta testing stage of my linear motor project.
Should resolve cogging issues normally appears with servo motors.

The problem is that klipper uses timers and synchronization to queue the commands Ahead of time so you would have to implement the entire sync and queue mechanism on odrive for it to function correctly.