Dangerous nozzle movements

341 views
Skip to first unread message

tony...@att.net

unread,
Jan 14, 2021, 12:37:34 PM1/14/21
to OpenPnP
Hey I just found a way to crash a nozzle tip.  Using the Jog Panel, lower the nozzle tip until it is just touching some object (like you want to find the z height of a part).  Then click on the "Move camera to position of selected nozzle button".  At that point the nozzle moves to safe z and the top camera moves over the position as it should.  Now jog the top camera (with either the jog buttons or using camera jog) over a taller part and click the "Move the selected nozzle to the camera position" button.  The nozzle moves over the new location and then attempts to lower to the z height of the original position which is of course lower than the z height of the current position so the nozzle tip crashes into the top of the taller part.  The really bad thing is that there is no indication to the operator that the nozzle tip is going to lower and by how much.

I believe the problem is due to my top camera having a virtual Z axis which is being set to the z coordinate of the nozzle tip when the "Move camera to position of selected nozzle button" is clicked.  I'm guessing that performing the horizontal jog just moves all Z axis to safe Z, does the jog, and then returns all Z axis to their prior setting.  Maybe virtual axis shouldn't be returned to their original settings after a horizontal jog?

Tony

ma...@makr.zone

unread,
Jan 14, 2021, 1:18:13 PM1/14/21
to ope...@googlegroups.com

Hi Tony

there are use cases where this behavior is wanted. The virtual Z axis of the camera is sort of the "memory" for Z.

Example use case:

  1. Say you wanted to capture a feeder pick location.
  2. First you locate it using the camera.
  3. Now you press the  button to bring the nozzle to the location.
  4. Lower the nozzle until the tip touches the feeder/part.
  5. You notice, "darn, I forgot the rotation".
  6. Bring the camera back with
  7. Rotate to the part's zero orientation.
  8. Press the capture button of the location panel. You get everything, including Z, because the virtual axis remembered.
  9. Or maybe you're unsure: "did I get the Z right?"
  10. Just press the again to check.

But you have the choice: If you think this is too dangerous/too unexpected, just unassign the virtual Z axis. Done.

Having said that: this should be improved by automatically selecting the right tool in Machine Controls, when you press or :

Plus we could disable the button for the tool that is already selected.

Once this is established, we are intuitively manipulating the right coordinates. So you can press P on the Z controls, to delete the Camera virtual Z.

This ways you could make such a move safe, prior to pressing  .

_Mark
--
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/96836bdb-91e1-4423-9850-897b4f817681n%40googlegroups.com.

tony...@att.net

unread,
Jan 14, 2021, 4:06:35 PM1/14/21
to OpenPnP
I agree in some cases it is exactly what the operator would want but in other cases it is not - even with your enhancements it's still the operator's burden to check the DRO before clicking the button.  Perhaps just a simple dialog box that pops-up a warning if the nozzle is about to be lowered below safe-z that gives the operator the option to do the move,, or to do the move but keep the nozzle at safe z, or to cancel?

Tony

ma...@makr.zone

unread,
Jan 15, 2021, 2:37:27 AM1/15/21
to ope...@googlegroups.com

Personally, I hate such modal dialogs. I'd rather add a second button, one with and one without Z.

_Mark

tony...@att.net

unread,
Jan 15, 2021, 11:26:02 AM1/15/21
to OpenPnP
Yeah, that would be fine with me.  Then at least the operator is making a conscientious decision.  What about making the original button only move the nozzle in safe Z and the new button make the complete move but the new button is only visible if in fact it would make the nozzle drop below safe Z (and it displays the Z value to which it will drop)?  Do we need a new icon?

Tony

ma...@makr.zone

unread,
Jan 15, 2021, 1:12:25 PM1/15/21
to ope...@googlegroups.com

I played around with it and IMHO the problem really is the missing automatic selection of the tool in Machine Controls.

Once we have this, the DRO will show you where it will go in Z:

Essentially it behaves the same way as if you would press any of the countless location panel buttons:

If you don't like the Z, you can reset it using P on the Z controls.

The Problem: the tool-tip "Move the selected nozzle to camera positon" is obviously wrong and we can't currently have it both ways: the DRO telling us the right target coordinates, and the selected tool telling us which nozzle to move (currently it'll move the default i.e. first nozzle, if the camera is selected).

:-(

One approach would be to remember which was the last active nozzle and make the tool-tip dynamic to tell us, which will be moved.

_Mark

tony...@att.net

unread,
Jan 15, 2021, 4:22:50 PM1/15/21
to OpenPnP
But doesn't that place the burden on the operator to remember to check the z value in the DRO before pressing the button.  In my case, a long time had elapsed between when I last pressed the "Move camera over the selected nozzle tip" button and when I pressed the "Move selected nozzle to the camera position" button.  In the intervening time I was busy jogging the camera all over the place and only when I got to some place that looked interesting (and was totally unrelated to the original location) did I press the "Move selected nozzle to the camera position" and was surprised when the nozzle slammed into the top of the part.

I guess it puzzles me why the virtual axis needs to work differently than a real axis.  The fact that the nozzle knows to retract to a safe z when I manually jog horizontally would seem to indicate to me that the camera should also retract to safe z (and stay there just like the nozzle does).  

Tony

John Plocher

unread,
Jan 15, 2021, 8:33:45 PM1/15/21
to ope...@googlegroups.com
IMO, the back and forth between camera and nozzle swapping has connotations of "same place", such at "feeder 12".
The manually set "Z" position of the nozzle also seems bound to that "place", such as for probing/setting pick height.

This leads to an assumption that feels "right":

If the head is moved somewhere and the Z position is manually set, then the Z position is remembered only while the head is at that "same place":
    • you can move Z up and down while in "nozzle" mode, 
    • it retracts to safe-Z when "camera" is chosen, and 
    • it returns if "nozzle" is chosen again.
if the head is manually moved at all (other than the swap nozzle and camera operation), then the remembered Z needs to be reset to safe-Z, because this is the ONLY safe operation possible.
To handle repetitive operations (like setting up a bank of feeders), you might have a shortcut or button that "remembers" that last Z so the user can recall it when the head is at a new position - but that saved Z should never be automatically recalled and used.

  -John


Jalan Kilat

unread,
Jan 15, 2021, 10:05:14 PM1/15/21
to ope...@googlegroups.com
hello, I'm looking for a pnp controller board that is ready to use, does anyone sell here?

ma...@makr.zone

unread,
Jan 16, 2021, 4:46:25 AM1/16/21
to ope...@googlegroups.com

tony> I guess it puzzles me why the virtual axis needs to work differently than a real axis.

No, the pattern is exactly the same i.e. symmetric. It is the classical moveToLocationAtSafe(). Yes, it does move all HeadMountables to safe Z in order to safely traverse in X/Y but then it lowers the HeadMountable it actually moves down in Z to the location. The only difference is that the camera Z is virtual and (more) obscured from the user.

https://github.com/openpnp/openpnp/blob/c6149415f40b7aca9760c6cd14cebd975b94c6c3/src/main/java/org/openpnp/gui/MachineControlsPanel.java#L307-L328

john> if the head is manually moved at all (other than the swap nozzle and camera operation), then the remembered Z needs to be reset to safe-Z

I like that criteria!

However, some tolerance would have to be applied, because adjusting a camera position slightly is IMHO often the purpose of switching back and forth between camera/nozzle, it should then still not lose Z.

We could add a tolerance of say 20mm around where the virtual Z was lowered. Once the user jogs the camera farther away, the virtual Z is automatically reset to Safe Z.

_Mark

tony...@att.net

unread,
Jan 16, 2021, 12:52:03 PM1/16/21
to OpenPnP
>No, the pattern is exactly the same i.e. symmetric. It is the classical moveToLocationAtSafe(). Yes, it does move all HeadMountables to safe Z in order to safely traverse in X/Y but then it lowers the HeadMountable it actually moves down in Z to the location. The only difference is that the camera Z is virtual and (more) obscured from the user.

Ok, if I lower the nozzle and the camera both below safe z and then do a horizontal move by clicking and dragging in the camera view, the nozzle goes to safe z and stays there but the camera goes back to its non-safe z:

2021-01-16 11:43:53.011 ReferenceHead DEBUG: H1.moveToSafeZ(1.0)
2021-01-16 11:43:53.011 AbstractHeadMountable DEBUG: Nozzle1.moveToSafeZ(1.0)
2021-01-16 11:43:53.011 ReferenceNozzle TRACE: Nozzle1.transformToHeadLocation((126.681822, 24.154086, -5.000000, 0.000000 mm), ...)
2021-01-16 11:43:53.011 AbstractHeadMountable DEBUG: Nozzle1.moveTo((43.660822, 0.708086, -5.000000, 0.000000 mm), 1.0)
2021-01-16 11:43:53.012 ReferenceNozzle TRACE: Nozzle1.transformToHeadLocation((126.681822, 24.154086, -5.000000, 0.000000 mm), ...)
2021-01-16 11:43:53.013 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M201.3   Z1377, 12000)...
2021-01-16 11:43:53.014 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(G1   Z-5.0000  F3098.37 ; move to target, 12000)...
2021-01-16 11:43:53.014 GcodeDriver TRACE: [serial://COM5] confirmed G1   Z-25.0000  F2190.89 
2021-01-16 11:43:53.014 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M201.3   Z1377
2021-01-16 11:43:53.014 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M400 ; Wait for moves to complete before returning, 12000)...
2021-01-16 11:43:53.014 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M114 ; get position, -1)...
2021-01-16 11:43:53.023 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.023 GcodeDriver TRACE: [serial://COM5] confirmed M201.3   Z1377
2021-01-16 11:43:53.023 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> G1   Z-5.0000  F3098.37 
2021-01-16 11:43:53.039 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.039 GcodeDriver TRACE: [serial://COM5] confirmed G1   Z-5.0000  F3098.37 
2021-01-16 11:43:53.039 GcodeDriver$ReaderThread TRACE: [serial://COM5] << qr:31, qi:1, qo:0
2021-01-16 11:43:53.040 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M400 
2021-01-16 11:43:53.935 GcodeDriver$ReaderThread TRACE: [serial://COM5] << qr:32, qi:0, qo:1
2021-01-16 11:43:53.935 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.935 GcodeDriver TRACE: [serial://COM5] confirmed M400 
2021-01-16 11:43:53.936 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M114 
2021-01-16 11:43:53.958 GcodeDriver$ReaderThread TRACE: [serial://COM5] << X:126.8041 Y:24.1941 Z:-5.0000 A:0.0000 B:0.0000 C:0.0000
2021-01-16 11:43:53.958 GcodeDriver TRACE: Position report: X:126.8041 Y:24.1941 Z:-5.0000 A:0.0000 B:0.0000 C:0.0000
2021-01-16 11:43:53.958 GcodeDriver TRACE: GcodeDriver got lastReportedLocation (x-non-square:126.804100, y:24.194100, z:-5.000000, rotation:0.000000)
2021-01-16 11:43:53.958 GcodeAsyncDriver TRACE: GcodeDriver confirmation complete.
2021-01-16 11:43:53.958 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.958 AbstractHeadMountable DEBUG: Down Camera.moveToSafeZ(1.0)
2021-01-16 11:43:53.958 AbstractHeadMountable DEBUG: Down Camera.moveTo((126.681822, 24.154086, 0.000000, 0.000000 mm), 1.0)
2021-01-16 11:43:53.959 AbstractHeadMountable DEBUG: Down Camera.moveTo((144.818186, 25.484607, 0.000000, 0.000000 mm), 1.0)
2021-01-16 11:43:53.961 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M201.3 X1446 Y106, 12000)...
2021-01-16 11:43:53.961 GcodeDriver TRACE: [serial://COM5] confirmed M114 
2021-01-16 11:43:53.961 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(G1 X144.9433 Y25.5246   F2958.64 ; move to target, 12000)...
2021-01-16 11:43:53.962 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M201.3 X1446 Y106
2021-01-16 11:43:53.962 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M400 ; Wait for moves to complete before returning, 12000)...
2021-01-16 11:43:53.963 GcodeAsyncDriver DEBUG: serial://COM5 commandQueue.offer(M114 ; get position, -1)...
2021-01-16 11:43:53.974 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.974 GcodeDriver TRACE: [serial://COM5] confirmed M201.3 X1446 Y106
2021-01-16 11:43:53.975 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> G1 X144.9433 Y25.5246   F2958.64 
2021-01-16 11:43:53.990 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:53.990 GcodeDriver TRACE: [serial://COM5] confirmed G1 X144.9433 Y25.5246   F2958.64 
2021-01-16 11:43:53.990 GcodeDriver$ReaderThread TRACE: [serial://COM5] << qr:31, qi:1, qo:0
2021-01-16 11:43:53.991 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M400 
2021-01-16 11:43:54.726 GcodeDriver$ReaderThread TRACE: [serial://COM5] << qr:32, qi:0, qo:1
2021-01-16 11:43:54.726 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:54.726 GcodeDriver TRACE: [serial://COM5] confirmed M400 
2021-01-16 11:43:54.726 GcodeAsyncDriver$WriterThread TRACE: [serial://COM5] >> M114 
2021-01-16 11:43:54.749 GcodeDriver$ReaderThread TRACE: [serial://COM5] << X:144.9433 Y:25.5246 Z:-5.0000 A:0.0000 B:0.0000 C:0.0000
2021-01-16 11:43:54.749 GcodeDriver TRACE: Position report: X:144.9433 Y:25.5246 Z:-5.0000 A:0.0000 B:0.0000 C:0.0000
2021-01-16 11:43:54.749 GcodeDriver TRACE: GcodeDriver got lastReportedLocation (x-non-square:144.943300, y:25.524600, z:-5.000000, rotation:0.000000)
2021-01-16 11:43:54.750 GcodeDriver$ReaderThread TRACE: [serial://COM5] << tinyg [mm] ok>
2021-01-16 11:43:54.749 GcodeAsyncDriver TRACE: GcodeDriver confirmation complete.
2021-01-16 11:43:54.750 AbstractHeadMountable DEBUG: Down Camera.moveTo((144.818186, 25.484607, -30.000000, 0.000000 mm), 1.0)

Jason von Nieda

unread,
Jan 16, 2021, 1:06:18 PM1/16/21
to ope...@googlegroups.com
Hi guys,

If I may jump in for a moment - I'm not going to delve into the details of the virtual axes, but I do want to mention the direction I'd like to go with safety and Z-probing in particular:

- I don't think the operator should be allowed to break the machine without being specifically told that is what will happen. The Juki I work on, for instance, won't even move if the door is open unless you turn a physical key, and then once you do turn the key the machine will only move at about 5% normal speed. To date, after placing millions of components, running 8 hours a day, we have broken 0 nozzles and have had 0 head crashes.

- Touching off Z should be a specific operation akin to Z probing. We already have a (very basic) Z probe system, and I think it should be extended to handle "manual" Z probing. Right now we support an Actuator as a Z probe. If we extended that to be able to select a nozzle we can make the distinction that the user must do a "manual" Z probe (by eye) with the nozzle when capturing a Z coordinate. It should be a modal operation where the user can lower the nozzle, capture the position, and then the nozzle returns to safe Z.

- I cannot think of a single reason we should ever allow XY to move with Z down in the "production" portions of the program. In machine setup, it's a different story. Of course we need to allow XYZ movements when setting up the tool changer, but I think that may be the only place. The operator should have to make a conscious decision to make this dangerous move; for example, perhaps on the tool changer wizard there is a "Unlock Nozzle Z" checkbox that must be set.

- I think it's important to differentiate between production and machine setup. It should be *extremely hard* to break something in normal production.

- Finally, I want to reiterate that my intention is to move OpenPnP towards a camera focused system. I intend to eventually remove the machine controls tool selection entirely. Positioning should be done with the camera and if a nozzle is needed it should be chosen automatically based on the operation taking place, i.e. based on the part being picked.

Thanks,
Jason




bert shivaan

unread,
Jan 16, 2021, 1:35:39 PM1/16/21
to OpenPnP
if we use a nozzle to open a blinds feeder or drag a feeder, then we need to move x/y while z is not "safe"?


Jason von Nieda

unread,
Jan 16, 2021, 1:36:37 PM1/16/21
to ope...@googlegroups.com
I’m only taking about user initiated movements here.

Jason


--
Sent from my BeOS enabled toaster

bert shivaan

unread,
Jan 16, 2021, 2:06:53 PM1/16/21
to OpenPnP
opps , my misread - sorry :)


ma...@makr.zone

unread,
Jan 16, 2021, 2:55:27 PM1/16/21
to ope...@googlegroups.com

Hi Jason

> Touching off Z

I don't understand (language). Could you explain? Thanks.

_Mark

Jason von Nieda

unread,
Jan 16, 2021, 2:59:26 PM1/16/21
to ope...@googlegroups.com
Sorry, CNC term. Touching off just means touching the tool to a surface to measure it's Z depth. In other words - a Z probe.

Jason


ma...@makr.zone

unread,
Jan 16, 2021, 4:18:02 PM1/16/21
to ope...@googlegroups.com

>Sorry, CNC term. Touching off just means touching the tool to a surface to measure it's Z depth. In other words - a Z probe.

Thanks.

> Finally, I want to reiterate that my intention is to move OpenPnP towards a camera focused system. I intend to eventually remove the machine controls tool selection entirely. Positioning should be done with the camera and if a nozzle is needed it should be chosen automatically based on the operation taking place, i.e. based on the part being picked.

The latest testing version goes 90% towards that goal. The selected tool will now automatically be selected through semantic user action.

I believe that routinely hiding the Machine Controls (a.k.a. "Productions Mode") is now a much more practical option.

I dared to default-enable it (subject to discussion). It can be switched off in the Machine:


John Plocher's idea to reset the virtual Z was implemented i.e. when the user moves the camera more than 5mm from the original position (where the Z was lowered) it will move the virtual Z to Safe Z. That should alleviate Tony's concerns.

Testing Version:

More info:

_Mark

John Plocher

unread,
Jan 16, 2021, 5:49:19 PM1/16/21
to ope...@googlegroups.com
>  move OpenPnP towards a camera focused system

Here's what my YX SMT550's UI looks like, for inspiration and/or comparison :-)

The machine's PnP software has a fixed size left/right panel design, with the machine and camera controls on the left, and the job/placement/feeder/... stuff on the right.
The machine controls are always shown, with head and conveyer UI inputs inactive while placement is running.  This gives the operator a conceptual "visual foundation" that doesn't change when navigating the rest of the UI, which lurches and jumps between popups, dialogs in Mandarin, interactive table editors, progress bars etc depending on where in the job setup/machine calibration / placement operations one might be...
IMG_0379.png

  • Under the camera display are controls to choose which of the cameras (head mounted down looking, hi-rez uplooking, or 1 of 4/6/8 per-nozzle high speed uplooking) to view, which lights to turn on/off (general flood or per-camera exposure controlled).  This part of the UI lets you dive into per-LED/per-camera exposure, contrast and intensity settings etc...
  • Under that is the DRO display for each nozzle
  • Finally is the machine control UI - head movement, conveyor controls and machine speed settings.
  • The reddish box is/will be a still snapshot of the latest uplooking component rotation pipeline.

The right side is full of chineseium based modal panels that are a big part of why people seem to absolutely hate the software supplied with these imported machines. 
Each of the colored boxes at the top of the "PCB Data Edit" window is a workflow step with its own obtuse and sometimes only partially translated UI - and yes, the specific colors seem to change randomly with software updates...

This is what you get after importing a job file:

IMG_3239.png

testing the mark/fiducial settings:

IMG_0382.png

These UI screens unfortunately only make sense in hindsight, after you internalize the production workflow (singular!) that the designers assumed you would be using.

This IMHO is the greatest impediment to using a PnP system - what makes perfect sense to the machine designers often makes no sense at all to the user!

In this case, the presumed workflow is: Machine calibration, job import, component ID, fiducial identification, per-component camera calibration, feeder/component loading and calibration followed by placing hundreds and hundreds of that same board every day.  i.e, everything is optimized for high volume single-design production lines where spending an hour or two setting up a job is "normal"; the real time savings are measured in placement efficiency that can shave seconds or minutes off of every board that flows thru the machine...


IMG_0383.png

As I said, this isn't a request to replicate any of this; rather I hope it injects some perspective of "how do other systems do it" into the brainstorming and design process.

    -John

Going way off topic, here are some shots of the SMT550's heads - note the (out of focus, sorry) lighting for the down looking camera, which has both a diffused LED panel around the camera itself and a pair of LED strips further away for general workspace lighting.  Each is independently controlled and calibrated.

IMG_0377.png
IMG_0378.png
IMG_0376.png

Ahh, *that's where that electrolytic ended up" :-)


Jason von Nieda

unread,
Jan 16, 2021, 7:09:57 PM1/16/21
to ope...@googlegroups.com
For what it's worth, I've been collecting screenshots of commercial machine interfaces for about 10 years now - so thank you for posting these - I'll add them to my list!

As a point of comparison, here's what the Juki's main "production" interface looks like:

Juki Production Panel.png




This is a Juki RS-1, purchased new in 2019. So, pretty close to state of the art.

I think this is a pretty good interface. There is no machine setup stuff, and it shows the operator what matters when they are running boards. It's sometimes a little too limiting, but it does have some good points. You can't edit board data without stopping production and going into the board editor. There are small changes you can make - tweaking XY, adjusting vision a bit, etc. but you can't, for instance, suddenly change the part or feeder assigned to a placement.

I think OpenPnP should be somewhere between where it is now and this interface. Far fewer foot guns than we have now, and with more of a focus on the interface showing what is important for the task you are doing.

As a simple example of something I'd like to change: I don't think the job controls should be shown unless you are in the process of targeting something. It certainly doesn't make sense to jog the machine while running a job, and I think it would be better if jogging was more related to the task at hand such as setting a feeder pick point.

Jason

--
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.
Reply all
Reply to author
Forward
0 new messages