Question about Advanced Motion Control

437 views
Skip to first unread message

ma...@makr.zone

unread,
Feb 11, 2021, 6:19:45 AM2/11/21
to OpenPnP

Hi Jaroslaw

Re-posting this in the group, so everbody can see it, hope you don't mind. I want this information to be open.

The ideal would be to implement the full 3rd order control inside the controller. Note, I made the planner code as "C++-like" as possible in Java, so I believe it could be ported quite easily, including the uncoordinated planning e.g. Motion Blending!!

https://github.com/openpnp/openpnp/blob/develop/src/main/java/org/openpnp/model/MotionProfile.java

https://github.com/openpnp/openpnp/blob/develop/src/main/java/org/openpnp/model/AbstractMotionPath.java

With 3rd order control in the controller, the amount of commands sent are small, no need for interpolation.

You could still implement the M595 options, especially the grace period (R word) would make sense.

Note: if this is intended for OpenPnP use only, then you can even avoid the need for a concurrent look-ahead-planner (which I think is very difficult to get right in hard real time). You can instead simply wait for M400 or the grace period timeout and then plan the whole motion sequence once only.

To test motion, you can simply use a GcodeAsyncDriver and the set it to use the internal Gcode simulator:

  • Switch to tcp
  • Set "GcodeServer" as the IP address (without the quotes)

You can also enable G-code logging in the driver. So you can extract the G-code as it is sent.

Note, some things would need to be defined for a true 3rd order motion controller. There is currently no standard G-code command to set the jerk for instance. I used M201.3 on the TinyG. But that is per-axis. It would be better to haven a tool-path relative jerk limit. If you commit to this, we can work new commands out.

_Mark


Am 11.02.2021 um 10:39 schrieb Jarosław Karwik:

Hi,

As I have been making my own controller ( https://groups.google.com/g/openpnp/c/oRY0dIKeIDw ) I wanted to ask you about best way to support your implementation of motion control features in OpenPnp.

- Should I implement  M595 for interpolated moves ? ( as my controller is ethernet based it can take fairly large amount of data - tens of gcode lines at once - so no need to send them one by one)

- Could you provide example of that gcode stream for such single move ? ( is there a way to simulate it / see it with null driver - I do not have smoothie to easilly see it)

I would go for direct 3rd order moves ( I have calcations ready, tested in simulations) - but then - how it would look like ? (especially in case of blended moves)


Best regards,

Jarosław karwik


Jarosław Karwik

unread,
Feb 11, 2021, 8:19:57 AM2/11/21
to OpenPnP
The idea was to make it open once we talk ;-)

I have working solution for calculating single 3rd order motion for one axis. I do not believe I could take yours without much of digging the code, these things are not exactly trivial.

But lets assume we have  maximum  speed,acceleration, jerk for path ( well, with know limits for single axis)
The you provide set of G commands with points.

It is trivial if the points are linear - but usually they are not.
What do you expect from the controller if there is like 30 deg turning  ( in X/Y plane) ?   I can either ignore the turn and calculate as if machine can take it , I can slow down or stop completely.

What is you practical experience when testing simulated 3rd order on smoothie and real machine ?

ma...@makr.zone

unread,
Feb 11, 2021, 1:05:26 PM2/11/21
to ope...@googlegroups.com

For OpenPnP almost every move is 90° to the next (Z vs. X/Y vs. Z). The machine needs to (almost*) stop in the corners.  So if you implement true 3rd order control (full 7 segments) even for single moves only, it is already big progress. It would be the first Open Source controller that I know that can do it.

The only thing that could change the 90° corners and allow speeding through would be Motion Blending:

https://github.com/openpnp/openpnp/wiki/Motion-Planner#motion-blending

So far I don't have high hopes that this can be done using interpolation. Even the most powerful controller (Duet 3) takes longer to receive the high volume of interpolated commands over USB than what time can be saved by speeding through corners. Unless USB bandwidth, command processing, look-ahead planning etc. can be improved by at least an order of magnitude, this will not be useful.

So the only hope is doing Motion Blending inside the controller. But I agree this is a big thing to integrate into an existing controller. The only "easy" way I see is starting from scratch, use a very powerful MCU with double precision FPU and port my code to C++.

Having said all that, there could be another way: I could send you finished profile segments. Each segment describes duration, start acceleration, end acceleration, start velocity, end velocity, start location, end location (redundancies could be optimized). Segments are per axis, and they can be uncoordinated i.e. different axis segments can have different durations and acceleration/velocity/displacement need not be proportional between axes. Typically, after a certain sequence of profile segments is complete, the durations will again add up to the same sum, e.g. when the axes go through a coordinated way-point ("corner").

For safety your controller could validate that

  1. the segments are continuous in acceleration, velocity, location (i.e. the integrals add up).
  2. they never exceed the controller's limits (jerk/acceleration/velocity/soft limits)
  3. they result in still-stand.

This way OpenPnP would become the de-factor motion planner, but the controller could still make sure everything is safe (a final responsibility that I would never be willing to transfer to OpenPnP). And of course the controller would still have to execute the (uncoordinated) segments in guaranteed real time and dither ramps to steps.

_Mark

*) You could allow a minimal speed through 90° corners, other controllers do it under the name of "Junction Deviation" or "Allowable Instant Velocity Change".

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/d50f903a-97aa-40b8-bcb5-f570071a360cn%40googlegroups.com.

Jarosław Karwik

unread,
Feb 11, 2021, 2:28:53 PM2/11/21
to OpenPnP
Hi,

I do have double precision FPU,  480Mhz clock and  1Mbyte of RAM  ( https://www.st.com/en/microcontrollers-microprocessors/stm32h743vi.html ). It is more powerfull then Duet board ( which is 300MHz / 384kB).


And the seven segment 3rd order motion is not that complicated - here is python emulation of what I have in my prototype ( both calculation and execution):

I do have an idea how to easilly implement motion blending, but I do not know if it can be described by pure  gcode ( which is a bit limiting in this case)
Imagine that you have simple XYZ setup.
And the move commands are like this:
- move Z from 0.0 to 5.0
- wait for Z passing 4.0
- move XY from 0.0, 0.0  to 10.0, 10.0  
- wait for XY passing 9.0, 9.0
- move Z from 5.0 to 0.0 

it is kind of event driven system which is easy to calculate and execute ( at least for my math and my controller principle) as it operate on simple independent trajectories which can be precalculated and synchronized with simple  delay counters  ( I use 64 bit fixed point math, so results are predictable).
This might not work for CNC but pick and place moves are mostly  like that. And you get motion blending for free.

So it would require just kind of parameterized M400 - something like 
M400.1 Z4.0
M400.1 X9.0 Y9.0


The second method you suggested - I actually use in my CNC controllers. The path is calculated on PC and sent to machine flash to be executed full speed. So this would be an option as well - but this one would not be gcode compliant either - so maybe the first one would be easier after all ? ( as it would not require validation of data).

ma...@makr.zone

unread,
Feb 12, 2021, 2:22:58 AM2/12/21
to ope...@googlegroups.com

Hi Jarosław

I don't see any problems for you to implement your own Motion Blending idea. The "corner" points remain the same and the motion can be sent as straight moves. Your controller must just know how much overshoot is admissible (Safe Z Zone). That's all.

_Mark

Jarosław Karwik

unread,
Feb 12, 2021, 5:39:58 AM2/12/21
to OpenPnP
Hi,

I have made few experiments.   "GcodeServer" works and allows checking gcode commands in log.

So I can enable "Full3rdOrderControl" to get motion segments  with feedrate( do we need acceleration/jerk  here as well or we use global settings ?)
 
Is there any way to know current SafeZ ?  ( from G code stream)  This would allow me process blending  internally.

ma...@makr.zone

unread,
Feb 12, 2021, 7:19:12 AM2/12/21
to ope...@googlegroups.com

> do we need acceleration/jerk  here as well or we use global settings ?

Acceleration should already be sent using M204, {Acceleration: } variable.

Jerk can be sent when you use the {Jerk: } variable. Like I said there is currently no established M-Command to send a dynamic Jerk limit known to me. I would suggest M204.3 with the same semantics as M204 but for 3rd order.

https://www.reprap.org/wiki/G-code#M204:_Set_default_acceleration

Something like this:

{Jerk:M204.3 S%.2f}

I guess this would need to be on a separate line to be G-code conformant. I could probably optimize it so it will only be issued if Jerk actually changed from the last move.

> Is there any way to know current SafeZ ?  ( from G code stream)  This would allow me process blending  internally.

No. I guess this should be a configuration on the controller that must match the configuration on OpenPnP. Like soft limits and other stuff too. This is a redundancy, yes, but I think it serves safety and is therefore OK as a kind of "double check".

_Mark

Jarosław Karwik

unread,
Feb 12, 2021, 7:29:34 AM2/12/21
to OpenPnP
Thanks for help - this actually answers all my questions ( at least for now :-) )

I will expand my python simulation script to be able to calculate moves like "up Z -> moveXY -> down Z" with motion blending for up and down moves to see how complicated it is.

We can also think at some point about gcode command to set the Z safe limit ( to be able to disable it for  )

And M204.3 sounds right as jerk setting parameter.

Jarosław Karwik

unread,
Feb 14, 2021, 1:33:53 PM2/14/21
to OpenPnP
Small playground :-)

run_3rd.png

The first plot shows simulated run of my algorithm ( I have calculated motion coefficients and run a loop which creates step signals).
Then I made reverse calculation - I have calculated time for given distance values ( 'zcut' ).
This will allow simple motion blending - I can calculate when Z axis reaches safe area and simple postpone XY movement for such time.
Same goes for the way down - I can easily calculate time needed to  pass safe Z area and start Z move down before XY finishes.
There is also one small special case when Z does not have enough time to go full up ( for short XY moves) - not sure if we have to worry about it - what if we have large component and risk banging already assembled ones ?

I need to solve one more thing - should I care much that in case of XY move the moves do not finish same time ? 
In case of 2nd order the speed calculation to fix it is easy, but 3rd order is more complicated here.

ma...@makr.zone

unread,
Feb 14, 2021, 1:52:51 PM2/14/21
to ope...@googlegroups.com

>There is also one small special case when Z does not have enough time to go full up ( for short XY moves) - not sure if we have to worry about it -

In my simulations it is significant. I made it adaptive to the X/Y distance. Note, for dual nozzle machines you also need the "snake" line, i.e. Z is overshooting, then reverting and then going further "up" which is "down" for the negated nozzle (shown in the two back rows):

> what if we have large component and risk banging already assembled ones ?

In my solution it only starts moving in X/Y if at safe Z. If Z is going up further it is just overshooting i.e. higher than needed. 

_Mark

ma...@makr.zone

unread,
Feb 14, 2021, 1:56:47 PM2/14/21
to ope...@googlegroups.com

Oh, and don't forget C can also be mixed in with X/Y.

_Mark

Jarosław Karwik

unread,
Feb 14, 2021, 2:23:23 PM2/14/21
to OpenPnP

How safe is safe Z ? 
Is it safe "enough" that it guarantees that the nozzle with longest component will safely fly over PCB with largest component assembled ? 
That was my understanding, although at some point  I started having my doubts.

The snake move means  checking range of Z values instead of single threshold - have to have it in mind when blending moves.

About C - I guess that this one usually also goes in safe Z area as well ?

When making XY move of 3rd order - have you been able to calculate it in such way that get straight line ( so the X and Y move ends  the same moment) ? I have some idea how it supposed to be calculated, but the algorithms seems pretty complicated and full of special cases. 

ma...@makr.zone

unread,
Feb 15, 2021, 2:33:52 AM2/15/21
to ope...@googlegroups.com

Answers inline>>

Am 14.02.2021 um 20:23 schrieb Jarosław Karwik:

How safe is safe Z ? 
Is it safe "enough" that it guarantees that the nozzle with longest component will safely fly over PCB with largest component assembled ?

It must be.

That was my understanding, although at some point  I started having my doubts.

Why?


The snake move means  checking range of Z values instead of single threshold - have to have it in mind when blending moves.



About C - I guess that this one usually also goes in safe Z area as well ?

Yes, it is handled exactly like X, Y.



When making XY move of 3rd order - have you been able to calculate it in such way that get straight line ( so the X and Y move ends  the same moment) ? I have some idea how it supposed to be calculated, but the algorithms seems pretty complicated and full of special cases. 

If you want that, it's easy: Just project all axis jerk/acceleration/feed-rate limits onto the tool-path (the "diagonal"). That is done by dividing the axis limits by the unit vector axis component. Take the minimum of the projected limits.

Then solve the profile for the tool-path and the projected minimum limits.

Then multiply everything by unit vector axis component to get the axis profiles.


But for the movement in the Safe Z Zone I do not use coordinated moves. It can be bit faster, if the axes have quite different limits i.e. if the ratio between acceleration and feed-rate limits varies (which can be the case in a Cartesian Machine, as the  Y axis is typically much heavier than X and especially C). 

_Mark


Jarosław Karwik

unread,
Feb 15, 2021, 3:01:18 AM2/15/21
to OpenPnP
At some point I lost my faith - whether safe Z guarantees no collision in all cases ( so including assembled PCB board versus nozzle loaded with component) or just safety of the nozzle ( so no hitting hard obstacles, but  so guarantees otherwise). But such case would be hard to control safely so the first case is the valid one - you are right here.

I will try the projection - I do something like this for 2nd order in my CNC controller, but did not believe it is that simple for 3rd order as well.

> But for the movement in the Safe Z Zone I do not use coordinated moves. It can be bit faster, if the axes have quite different limits i.e. if the ratio between acceleration and feed-rate
> limits varies (which can be the case in a Cartesian Machine, as the  Y axis is typically much heavier than X and especially C). 

Well C does not have to be coordinated - for sure, just that it is kept in safe zone.
Well, I guess coordinated moves are not needed in safe zone either - unless we get fly camera at some point :-)

But then - is there any valid case when coordinated moves are being used ?  Hard to imagine XY move in non-safe zone ( with exception of some unique machines using nozzle to advance tape in feeder)

ma...@makr.zone

unread,
Feb 15, 2021, 4:03:58 AM2/15/21
to ope...@googlegroups.com

It is as simple as that for any order due to how derivatives of power functions work (i.e. simply with a fixed factor of the exponent):

https://simple.wikipedia.org/wiki/Derivative_(mathematics)#Power_functions

_Mark

ma...@makr.zone

unread,
Feb 15, 2021, 4:16:34 AM2/15/21
to ope...@googlegroups.com

> But then - is there any valid case when coordinated moves are being used ?  Hard to imagine XY move in non-safe zone ( with exception of some unique machines using nozzle to advance tape in feeder)

Yes, for nozzle tip changing or feeder actuation. There can be diagonal moves in space. 

Source: https://wiki.apertus.org/index.php/Liteplacer_PnP_Machine_Notes

https://youtu.be/5QcJ2ziIJ14?t=255

_Mark


Am 15.02.2021 um 09:01 schrieb Jarosław Karwik:
You received this message because you are subscribed to a topic in the Google Groups "OpenPnP" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/openpnp/Y--rrV9e3AQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/d0701b40-ad42-4241-9a6f-c550499baae5n%40googlegroups.com.

Jarosław Karwik

unread,
Feb 15, 2021, 4:46:46 AM2/15/21
to OpenPnP
You are right again.

I can imagine that you could have both feeder and nozzle changer moves both in safe and non-safe mode.

Does OpenPnp use G0 / G1 to distinguish between linear and rapid moves ? ( this would be the safest way to determine when/if  liner/coordinate move is needed)

ma...@makr.zone

unread,
Feb 15, 2021, 4:57:43 AM2/15/21
to ope...@googlegroups.com

> Does OpenPnp use G0 / G1 to distinguish between linear and rapid moves ?

Not yet. That is on my list.

It will probably never be introduced by default because some controllers have very "strong" ideas about G0 (like not applying/allowing any rate limits). Also, it is very important that there is no deceleration when switching from G0 to G1 and vice versa.

But I will make it available as an optional Gcode variable in some upcoming version.

_Mark

Jarosław Karwik

unread,
Feb 19, 2021, 7:10:39 AM2/19/21
to OpenPnP
Mark,

You have showed nice simulation few posts before - do you have matching G code sequence ?
I would like to use it as test vector when developing my motion planner

Jarek

ma...@makr.zone

unread,
Feb 19, 2021, 7:25:27 AM2/19/21
to ope...@googlegroups.com

Do you mean this?


No, this is only a Java test unit that tests the motion solver.

If you want G-code, best create a test motion:

https://github.com/openpnp/openpnp/wiki/Motion-Planner#settings

Then connect to the simulation GcodeServer:

Then enabled G-code logging (starts as soon you press Apply):

Then test:

https://github.com/openpnp/openpnp/wiki/Motion-Planner#test-motion

Then disable G-code logging (stops as soon as you press Apply).

_Mark

Jarosław Karwik

unread,
Feb 19, 2021, 3:35:52 PM2/19/21
to OpenPnP

Thanks,

I have tried already the simulator, I will use its output for first tests.

Just that output of your Java test looked really interesting :-). I will manually recreate part of it - especially the cases with shared Z axis.

ma...@makr.zone

unread,
Feb 20, 2021, 4:34:15 AM2/20/21
to ope...@googlegroups.com

Unit Test is here:

https://github.com/openpnp/openpnp/blob/d539596aae8a455b737929545187ff9c0cf4cc78/src/test/java/AdvancedMotionTest.java#L340

It compares the scenario with/without jerk control (at two jerk rates), with/without motion blending.

_Mark

Jarosław Karwik

unread,
Feb 21, 2021, 11:30:27 AM2/21/21
to OpenPnP
Thanks.
I will use the sequence for my testing.

One question about this part:

// move to push/pull feeder

path.moveTo(200, 50, safeZ, 1);

path.moveTo(220, 50, safeZ-5, 1);

path.moveTo(220, 50, safeZ, 1);

path.moveTo(200, 80, safeZ, 1);

path.moveTo(190, 100, safeZ, 1);

path.moveTo(190, 120, safeZ, 1);

path.moveTo(300, 120, za, 1);

path.moveTo(300, 150, za, 1);

path.moveTo(280, 150, za, 1);

path.moveTo(279, 150, za, 1);

path.moveTo(275, 150, za, 1);
path.moveTo(275, 150, safeZ, 1);

This is operation for feeder control ?
How do you execute these moves ?  Do you fully stop for each one or you join them ?

ma...@makr.zone

unread,
Feb 21, 2021, 12:05:41 PM2/21/21
to ope...@googlegroups.com

This sequence is just to test that nothing bad happens, if unusual motion is planned. A PushPullFeeder or a nozzle tip changer could create motion like that.

My planner can handle coordinated->coordinate (endless, straight lines), and coordinated->uncoordinated->coordinated (with motion blending).

But if unccordinated->uncoodinated happens, it will stop at the junction i.e. this is not (yet) implemented. This is very hard to optimize.

_Mark

Jarosław Karwik

unread,
Feb 22, 2021, 4:26:24 AM2/22/21
to OpenPnP
Yes, and these unccordinated->uncoodinated should be rare - after all feeders/nozzle tip changers need to be coordinated.

I will do my planner first in Python, so I can see results much easier. I even thought of embedding micro Python into the device, although I am not sure about the processing power penalty ( it supposed to be small for precompiled byte code)

I still need to solve rotation commands added to XY moves, but I guess it either fits into the "safe zone" area of XY moves or it requires full stop ( if it does not).

ma...@makr.zone

unread,
Feb 22, 2021, 5:40:59 AM2/22/21
to ope...@googlegroups.com

> I still need to solve rotation commands added to XY moves

In my code there is no difference between X, Y, and C. It is just one axis more.

_Mark

Jarosław Karwik

unread,
Feb 25, 2021, 12:21:13 PM2/25/21
to OpenPnP
After some experiments...... our pictures combined:

blending.png
Now I think I understand your algorithm - the safe zone ( -7.5...7.5 ) is being used as buffer for Z motion ( slowing/speeding ).

But outside test - how do you know ( from the OpenPnp gcodes) that blending is allowed ?  When e.g. you have servicing nozzle changer or feeder lever ?
Reply all
Reply to author
Forward
0 new messages